From 0c90326adae7d5b7be9e799fd73fb4765b49741e Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 14 Dec 2021 18:49:17 +0000 Subject: [PATCH 01/60] Update: Translations from eints swedish: 1 change by joeax910 chinese (traditional): 160 changes by Tetrapod1206 galician: 21 changes by pvillaverde irish: 5 changes by temuchie polish: 2 changes by pAter-exe --- src/lang/galician.txt | 42 ++++---- src/lang/irish.txt | 8 +- src/lang/polish.txt | 2 + src/lang/swedish.txt | 1 + src/lang/traditional_chinese.txt | 170 +++++++++++++++++++++++++++++-- 5 files changed, 189 insertions(+), 34 deletions(-) diff --git a/src/lang/galician.txt b/src/lang/galician.txt index 5429f5e640..c5817d0f47 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -138,7 +138,7 @@ STR_ABBREV_GOODS :{TINY_FONT}ME STR_ABBREV_GRAIN :{TINY_FONT}GR STR_ABBREV_WOOD :{TINY_FONT}MA STR_ABBREV_IRON_ORE :{TINY_FONT}FE -STR_ABBREV_STEEL :{TINY_FONT}AC +STR_ABBREV_STEEL :{TINY_FONT}AÇ STR_ABBREV_VALUABLES :{TINY_FONT}VA STR_ABBREV_COPPER_ORE :{TINY_FONT}CO STR_ABBREV_MAIZE :{TINY_FONT}MI @@ -845,7 +845,7 @@ STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Nova {STRING} asentada preto de {TOWN}! STR_NEWS_INDUSTRY_CLOSURE_GENERAL :{BIG_FONT}{BLACK}{STRING} anuncia o seu peche inminente! -STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS :{BIG_FONT}{BLACK}Problemas de subministración en {STRING} provocan que anuncie o seu peche inminente! +STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS :{BIG_FONT}{BLACK}Problemas de abastecemento en {STRING} provocan que anuncie o seu peche inminente! STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES :{BIG_FONT}{BLACK}A falta de árbores cercanos provoca que {STRING} anuncie o peche inminente! STR_NEWS_EURO_INTRODUCTION :{BIG_FONT}{BLACK}Unión Económica e Monetaria Europea!{}{}O Euro introdúcese como a única moeda para as transaccións diarias no teu país! @@ -2617,7 +2617,7 @@ STR_STATION_BUILD_COVERAGE_ON :{BLACK}On STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Non resalta-la área de cobertura do sitio proposto STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Resalta-la área de cobertura do sitio proposto STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Acepta: {GOLD}{CARGO_LIST} -STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Suministros: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Abastecementos: {GOLD}{CARGO_LIST} # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Unir estación @@ -3550,7 +3550,7 @@ STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY :{YELLOW}{COMPAN STR_STATION_VIEW_RATINGS_BUTTON :{BLACK}Puntuacións: STR_STATION_VIEW_RATINGS_TOOLTIP :{BLACK}Mostra-las puntuacións da estación -STR_STATION_VIEW_SUPPLY_RATINGS_TITLE :{BLACK}Suministro mensual e puntuación local: +STR_STATION_VIEW_SUPPLY_RATINGS_TITLE :{BLACK}Abastecemento mensual e puntuación local: STR_STATION_VIEW_CARGO_SUPPLY_RATING :{WHITE}{STRING}: {YELLOW}{COMMA} / {STRING} ({COMMA}%) STR_STATION_VIEW_GROUP :{BLACK}Agrupar por @@ -4136,7 +4136,7 @@ STR_VEHICLE_VIEW_AIRCRAFT_STATUS_START_STOP_TOOLTIP :{BLACK}Acción STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}Cargando / Descargando STR_VEHICLE_STATUS_LEAVING :{LTBLUE}Saíndo STR_VEHICLE_STATUS_CRASHED :{RED}Estrelado! -STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Roto +STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Avariado STR_VEHICLE_STATUS_STOPPED :{RED}Parado STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}Parando, {VELOCITY} STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}Sen enerxía @@ -5102,7 +5102,7 @@ STR_INDUSTRY_NAME_DIAMOND_MINE :Mina de diamant STR_INDUSTRY_NAME_IRON_ORE_MINE :Mina de ferro STR_INDUSTRY_NAME_FRUIT_PLANTATION :Plantación de froita STR_INDUSTRY_NAME_RUBBER_PLANTATION :Plantación de sobreiras -STR_INDUSTRY_NAME_WATER_SUPPLY :Subministro de auga +STR_INDUSTRY_NAME_WATER_SUPPLY :Abastecemento de auga STR_INDUSTRY_NAME_WATER_TOWER :Torre de auga STR_INDUSTRY_NAME_FACTORY_2 :Fábrica STR_INDUSTRY_NAME_FARM_2 :Granxa @@ -5198,20 +5198,20 @@ STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COAL_CAR :Coche de Carbó STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_OIL_TANKER :Tanque de Petróleo STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_LIVESTOCK_VAN :Furgón de Gando STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_GOODS_VAN :Furgón de Mercadorías -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_GRAIN_HOPPER :Tolva de Gran +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_GRAIN_HOPPER :Tremoia de Gran STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WOOD_TRUCK :Vagón de Madeira -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_IRON_ORE_HOPPER :Tolva de Hematita +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_IRON_ORE_HOPPER :Tremoia de Hematita STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_STEEL_TRUCK :Vagón de Aceiro STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_ARMORED_VAN :Furgón Blindado STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FOOD_VAN :Furgón de Comida STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PAPER_TRUCK :Vagón de Papel -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COPPER_ORE_HOPPER :Tolva de Mineral de Cobre +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COPPER_ORE_HOPPER :Tremoia de Mineral de Cobre STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WATER_TANKER :Tanque de Auga STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FRUIT_TRUCK :Vagón de Froitas STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_RUBBER_TRUCK :Vagón de Caucho STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_SUGAR_TRUCK :Vagón de Azucre -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COTTON_CANDY_HOPPER :Tolva de Algodón de Azucre -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOFFEE_HOPPER :Tolva de Toffee +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COTTON_CANDY_HOPPER :Tremoia de Algodón de Azucre +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOFFEE_HOPPER :Tremoia de Toffee STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_BUBBLE_VAN :Furgón de Burbullas STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COLA_TANKER :Tanque de Cola STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_CANDY_VAN :Furgón de Caramelos @@ -5228,20 +5228,20 @@ STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COAL_CAR :Coche de Carbó STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_OIL_TANKER :Tanque de Petróleo STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_LIVESTOCK_VAN :Furgón de Gando STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_GOODS_VAN :Furgón de Mercadorías -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_GRAIN_HOPPER :Tolva de Gran +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_GRAIN_HOPPER :Tremoia de Gran STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_WOOD_TRUCK :Vagón de Madeira -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_IRON_ORE_HOPPER :Tolva de Hematita +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_IRON_ORE_HOPPER :Tremoia de Hematita STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_STEEL_TRUCK :Vagón de Aceiro STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_ARMORED_VAN :Furgón Blindado STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FOOD_VAN :Furgón de Comida STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PAPER_TRUCK :Vagón de Papel -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COPPER_ORE_HOPPER :Tolva de Mineral de Cobre +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COPPER_ORE_HOPPER :Tremoia de Mineral de Cobre STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_WATER_TANKER :Tanque de Auga STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FRUIT_TRUCK :Vagón de Froitas STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_RUBBER_TRUCK :Vagón de Caucho STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_SUGAR_TRUCK :Vagón de Azucre -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COTTON_CANDY_HOPPER :Tolva de Algodón de Azucre -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOFFEE_HOPPER :Tolva de Toffee +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COTTON_CANDY_HOPPER :Tremoia de Algodón de Azucre +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOFFEE_HOPPER :Tremoia de Toffee STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BUBBLE_VAN :Furgón de Burbullas STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COLA_TANKER :Tanque de Cola STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_CANDY_VAN :Furgón de Caramelos @@ -5260,20 +5260,20 @@ STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COAL_CAR :Coche de Carbó STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_OIL_TANKER :Tanque de Petróleo STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_LIVESTOCK_VAN :Furgón de Gando STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_GOODS_VAN :Furgón de Mercadorías -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_GRAIN_HOPPER :Tolva de Gran +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_GRAIN_HOPPER :Tremoia de Gran STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_WOOD_TRUCK :Vagón de Madeira -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_IRON_ORE_HOPPER :Tolva de Hematita +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_IRON_ORE_HOPPER :Tremoia de Hematita STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_STEEL_TRUCK :Vagón de Aceiro STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_ARMORED_VAN :Furgón Blindado STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FOOD_VAN :Furgón de Comida STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PAPER_TRUCK :Vagón de Papel -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COPPER_ORE_HOPPER :Tolva de Mineral de Cobre +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COPPER_ORE_HOPPER :Tremoia de Mineral de Cobre STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_WATER_TANKER :Tanque de Auga STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FRUIT_TRUCK :Vagón de Froitas STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_RUBBER_TRUCK :Vagón de Caucho STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_SUGAR_TRUCK :Vagón de Azucre -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COTTON_CANDY_HOPPER :Tolva de Algodón de Azucre -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_TOFFEE_HOPPER :Tolva de Toffee +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COTTON_CANDY_HOPPER :Tremoia de Algodón de Azucre +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_TOFFEE_HOPPER :Tremoia de Toffee STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BUBBLE_VAN :Furgón de Burbullas STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COLA_TANKER :Tanque de Cola STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_CANDY_VAN :Furgón de Caramelos diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 88d8449d96..9341b996cd 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -205,7 +205,7 @@ STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg STR_UNITS_WEIGHT_LONG_IMPERIAL :{COMMA}{NBSP}tona -STR_UNITS_WEIGHT_LONG_METRIC :{COMMA}{NBSP}{P "th" "th" "th" "dt" "th"}ona +STR_UNITS_WEIGHT_LONG_METRIC :{COMMA}{NBSP}{P "th" "th" "th" "dt" "t"}ona STR_UNITS_WEIGHT_LONG_SI :{COMMA}{NBSP}kg STR_UNITS_VOLUME_SHORT_IMPERIAL :{COMMA}{NBSP}gal @@ -855,7 +855,7 @@ STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_COAL :{BIG_FONT}{BLACK}Aimsítear síog ghuail nua ag {INDUSTRY}!{}Meastar go dtiocfaidh méadú faoi dhó ar tháirgeadh! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_OIL :{BIG_FONT}{BLACK}Aimsítear stoc ola nua ag {INDUSTRY}!{}Meastar go dtiocfaidh méadú faoi dhó ar tháirgeadh! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM :{BIG_FONT}{BLACK}Meastar go dtiocfaidh méadú faoi dhó ar tháirgeadh ag {INDUSTRY} mar gheall ar feabhsuithe sna modhanna feirmeoireachta! -STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK}Tagann méadú ar tháirgeadh {STRING} ag {INDUSTRY} de {COMMA}%! +STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK}Tháing méadú {2:COMMA}% ar tháirgeadh '{0:STRING}' ag {1:INDUSTRY}! STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL :{BIG_FONT}{BLACK}Tagann laghdú 50% ar tháirgeadh ag {INDUSTRY} STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM :{BIG_FONT}{BLACK}Déantar robach de bharr inmhíolú feithidí ag {INDUSTRY}!{}Lagdhú 50% ar tháirgeadh STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK}Tagann laghdú ar tháirgeadh {STRING} ag {INDUSTRY} de {COMMA}%! @@ -1031,7 +1031,7 @@ STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Roghnaig STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(uath-aimsiú) STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Gnáth STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Méid dúbailte -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Méid cheathrúil +STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Méid 4x STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Méid na clófhoirne STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Roghnaigh méid na clófhoirne don chomhéadan a úsáidfear @@ -1739,6 +1739,7 @@ STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT :Taispeáin nuac STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :Timpistí / tubaistí: {STRING} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :Taispeáin nuachtán nuair a thiteann timpistí nó tubaistí amach +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER :Timpistí de chuid fheithiclí na n-iomaitheoirí: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :Faisnéis cuideachta: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :Taispeáin nuachtán nuair a thosaíonn cuideachta nua, nó nuair atá cuideachta i mbaol féimheachta @@ -2252,6 +2253,7 @@ STR_NETWORK_SERVER_LIST_LANDSCAPE :{SILVER}Tírdhr STR_NETWORK_SERVER_LIST_MAP_SIZE :{SILVER}Méid na léarscáile: {WHITE}{COMMA}x{COMMA} STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Leagan an fhreastalaí: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Seoladh an fhreastalaí: {WHITE}{STRING} +STR_NETWORK_SERVER_LIST_INVITE_CODE :{SILVER}Cód an chuiridh: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Dáta tosaigh: {WHITE}{DATE_SHORT} STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}Dáta reatha: {WHITE}{DATE_SHORT} STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}Script Cluiche: {WHITE}{STRING} (v{NUM}) diff --git a/src/lang/polish.txt b/src/lang/polish.txt index c621eb314e..77369b0f88 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -2123,6 +2123,8 @@ STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT :Wyświetl wiado STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :Wypadki / klęski: {STRING} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :Wyświetl wiadomość w gazecie kiedy zdarzy się wypadek lub nastąpi katastrofa +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER :Wypadki pojazdów konkurentów: {STRING} +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER_HELPTEXT :Wyświetl wiadomość w gazecie o rozbitych pojazdach konkurentów STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :Informacja firmy: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :Wyświetl wiadomość w gazecie kiedy powstaje nowa firma lub kiedy istniejącym firmom grozi bankructwo diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index a39e3925ae..f63ac4e02d 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -1743,6 +1743,7 @@ STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT :Visa nyhetstidn STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :Olyckor / katastrofer: {STRING} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :Visa nyhetstidning när olyckor eller katastrofer inträffar +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER :Olyckor med konkurrenters fordon: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :Företagsinformation: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :Visa nyhetstidning när nya företag startar upp eller när ett befintligt företag riskerar att gå bankrupt diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 941462a079..c5994ee5c1 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -188,6 +188,7 @@ STR_COLOUR_ORANGE :橙 STR_COLOUR_BROWN :棕 STR_COLOUR_GREY :灰 STR_COLOUR_WHITE :白 +STR_COLOUR_RANDOM :隨機 # Units used in OpenTTD STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}英里/小時 @@ -263,6 +264,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}如啟 STR_BUTTON_DEFAULT :{BLACK}預設值 STR_BUTTON_CANCEL :{BLACK}取消 STR_BUTTON_OK :{BLACK}確定 +STR_WARNING_PASSWORD_SECURITY :{YELLOW}警告: 伺服器管理者可能可以閱讀在此處輸入的任何文字訊息 # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -312,9 +314,13 @@ STR_SORT_BY_RANGE :範圍 STR_SORT_BY_POPULATION :人口 STR_SORT_BY_RATING :評價 STR_SORT_BY_NUM_VEHICLES :車輛數量 +STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :去年總盈利 +STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR :今年總盈利 +STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :去年平均盈利 # Group by options for vehicle list STR_GROUP_BY_NONE :無 +STR_GROUP_BY_SHARED_ORDERS :共享指令 # Order button in shared orders vehicle list @@ -363,6 +369,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}產生 STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}產生市鎮 STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}產生工業 STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}建造道路 +STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}鋪設電車軌 STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}植樹。按 Shift 可切換種植/顯示預估的種植費用 STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}放置標誌 STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}放置物件。按 Shift 可切換興建/顯示預估的興建費用 @@ -777,6 +784,7 @@ STR_STATUSBAR_PAUSED :{YELLOW}* * STR_STATUSBAR_AUTOSAVE :{RED}自動儲存 STR_STATUSBAR_SAVING_GAME :{RED}* * 遊戲儲存中 * * +STR_STATUSBAR_SPECTATOR :{WHITE}旁觀者 # News message history STR_MESSAGE_HISTORY :{WHITE}訊息記錄 @@ -878,7 +886,12 @@ STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO :{WHITE}{STATION STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED :{BIG_FONT}{BLACK}補助過期:{}{}將 {STRING} 從 {STRING} 運到 {STRING} 現在起不再提供補助 STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLACK}補助結束:{}{}將 {STRING} 從 {STRING} 運到 {STRING} 的服務不再提供補助 +STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}提供補助:{}{}首先將 {STRING} 從 {STRING} 運到 {STRING} 的公司將得到地方政府補助{NUM}年! ###length 4 +STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}{STRING} 獲得補助!{}{}將 {STRING} 從 {STRING} 運到 {STRING} 的服務可在往後{NUM}年收到額外 50% 的運費補助! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}{STRING} 獲得補助!{}{}將 {STRING} 從 {STRING} 運到 {STRING} 的服務可在往後{NUM}年收到雙倍運費補助! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}{STRING} 獲得補助!{}{}將 {STRING} 從 {STRING} 運到 {STRING} 的服務可在往後{NUM}年收到三倍運費補助! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}{STRING} 獲得補助!{}{}將 {STRING} 從 {STRING} 運到 {STRING} 的服務可在往後{NUM}年收到四倍運費補助! STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}{TOWN} 交通大亂!{}{}{STRING} 出資的道路重建計劃為用路人帶來六個月的惡夢! STR_NEWS_EXCLUSIVE_RIGHTS_TITLE :{BIG_FONT}{BLACK}運輸大亨! @@ -918,7 +931,7 @@ STR_GAME_OPTIONS_CURRENCY_NLG :荷蘭盾 (NLG) STR_GAME_OPTIONS_CURRENCY_NOK :挪威克朗 (NOK) STR_GAME_OPTIONS_CURRENCY_PLN :波蘭茲羅提 (PLN) STR_GAME_OPTIONS_CURRENCY_RON :羅馬尼亞列伊 (RON) -STR_GAME_OPTIONS_CURRENCY_RUR :俄羅斯盧布 (RUR) +STR_GAME_OPTIONS_CURRENCY_RUR :俄羅斯舊盧布 (RUR) STR_GAME_OPTIONS_CURRENCY_SIT :斯洛文尼亞托拉 (SIT) STR_GAME_OPTIONS_CURRENCY_SEK :瑞典克朗 (SEK) STR_GAME_OPTIONS_CURRENCY_TRY :土耳其里拉 (TRY) @@ -931,13 +944,17 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :南非蘭特 (Z STR_GAME_OPTIONS_CURRENCY_CUSTOM :自訂... STR_GAME_OPTIONS_CURRENCY_GEL :喬治亞拉里 (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :伊朗里亞爾 (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :俄羅斯盧布 (RUB) +STR_GAME_OPTIONS_CURRENCY_CNY :中國人民幣(CNY) STR_GAME_OPTIONS_CURRENCY_HKD :港幣 (HKD) +STR_GAME_OPTIONS_CURRENCY_INR :印度盧比(INR) +STR_GAME_OPTIONS_CURRENCY_IDR :印尼盾 (IDR) ###length 2 STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :靠左行駛 STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :靠右行駛 -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}市鎮名稱 +STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}市鎮名稱: STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}選擇市鎮命名風格 ###length 21 @@ -984,8 +1001,12 @@ STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}勾選 STR_GAME_OPTIONS_RESOLUTION :{BLACK}螢幕解析度 STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}選擇螢幕解析度 STR_GAME_OPTIONS_RESOLUTION_OTHER :其它 +STR_GAME_OPTIONS_RESOLUTION_ITEM :{NUM}x{NUM} +STR_GAME_OPTIONS_VIDEO_ACCELERATION :{BLACK}硬體加速 +STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync +STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}勾選此方框以啟用V-SYNC。此項設定將會在遊戲重啟後套用。只有在硬體加速存在時可用 STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}介面大小 STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}選擇使用的介面元素大小 @@ -995,8 +1016,13 @@ STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :兩倍大小 STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :四倍大小 +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(自動偵測) +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :兩倍大小 +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :四倍大小 +STR_GAME_OPTIONS_GRAPHICS :{BLACK}圖形 +STR_GAME_OPTIONS_REFRESH_RATE_ITEM :{NUM}Hz STR_GAME_OPTIONS_BASE_GRF :{BLACK}基本圖形集 STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}選擇要使用的基本圖形集 @@ -1098,6 +1124,7 @@ STR_TERRAIN_TYPE_FLAT :平坦 STR_TERRAIN_TYPE_HILLY :丘陵 STR_TERRAIN_TYPE_MOUNTAINOUS :高山 STR_TERRAIN_TYPE_ALPINIST :多山 +STR_TERRAIN_TYPE_CUSTOM :自訂高度 STR_TERRAIN_TYPE_CUSTOM_VALUE :自訂高度({NUM}) ###length 3 @@ -1112,6 +1139,7 @@ STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}顯示 STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}篩選字串: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}展開所有選項 STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}折疊所有選項 +STR_CONFIG_SETTING_RESET_ALL :{BLACK}重設所有數值 STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(沒有適用的解釋) STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}預設值: {ORANGE}{STRING} STR_CONFIG_SETTING_TYPE :{LTBLUE}設定種類: {ORANGE}{STRING} @@ -1120,6 +1148,7 @@ STR_CONFIG_SETTING_TYPE_GAME_MENU :遊戲設定 ( STR_CONFIG_SETTING_TYPE_GAME_INGAME :遊戲設定 (存檔時保存;僅影響現時開啟的遊戲) STR_CONFIG_SETTING_TYPE_COMPANY_MENU :公司設定 (存檔時保存;僅在往後建立的新遊戲生效) STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :公司設定 (存檔時保存;僅影響您正在控制的公司) +STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT :{WHITE}此操作將會還原所有遊戲設定至預設狀態{}你確定要進行此操作嗎? STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}篩選設定: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}適用範圍: @@ -1184,6 +1213,7 @@ STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :設定獲補助 ###setting-zero-is-special +STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :沒有補貼 STR_CONFIG_SETTING_CONSTRUCTION_COSTS :建造成本: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :設定建造和購買物件的成本水平 @@ -1200,8 +1230,10 @@ STR_CONFIG_SETTING_DISASTERS_HELPTEXT :切換那些有 STR_CONFIG_SETTING_CITY_APPROVAL :地方政府對地區結構重組的態度: {STRING} STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :選擇公司所製造的噪音和環境傷害對其在市鎮的評比及未來的建設行動會造成多大影響 +STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :地圖高度限制: {STRING} +STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_VALUE :{NUM} ###setting-zero-is-special -STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}您不能把地圖的最高高度設成此值。至少有一座山比這個高度更高。 +STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}您不能把地圖的最大高度限制設成此值。至少有一座山比這個高度更高。 STR_CONFIG_SETTING_AUTOSLOPE :允許在建築物或軌道底下改變地形斜度 (autoslope):{STRING} STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :可以在建築物或軌道底下改變地形而不需移除它們 @@ -1330,6 +1362,7 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}當有 STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :基礎建設維護: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :如啟用此選項,基礎建設會產生維護成本。該成本的增長會根據公司基礎建設的規模而加倍增大,因此該設定對大公司的影響比對小公司更大 +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :選擇公司的初始顏色 STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :機場永不過期:{STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :如啟用此選項,所有機場一經面世,就永遠可以選擇建設 @@ -1454,6 +1487,7 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :暗綠 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :紫 ###length 4 +STR_CONFIG_SETTING_SCROLLMODE_RMB :使用右鍵移動地圖 STR_CONFIG_SETTING_SCROLLMODE_LMB :使用左鍵移動地圖 STR_CONFIG_SETTING_SMOOTH_SCROLLING :視野平滑移動:{STRING} @@ -1491,6 +1525,7 @@ STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :單撳 (選定 STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK :單撳 (立刻) ###length 3 +STR_CONFIG_SETTING_USE_RELAY_SERVICE_ALLOW :允許 STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU :右鍵模擬:{STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT :選擇模擬右撳鼠鍵的方法 @@ -1499,6 +1534,8 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command 鍵 STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Control 鍵 STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :無 +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :右鍵關閉視窗: {STRING} +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :在視窗內以右鍵點擊可關閉視窗。可用右鍵關閉工具提示 STR_CONFIG_SETTING_AUTOSAVE :自動儲存: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :選擇自動存檔的週期 @@ -1552,7 +1589,10 @@ STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :設定是否在 STR_CONFIG_SETTING_EXPENSES_LAYOUT :將公司財務視窗的收支分組顯示:{STRING} STR_CONFIG_SETTING_EXPENSES_LAYOUT_HELPTEXT :決定是否將公司財務視窗內的收支項目分組顯示 +STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :在鋪設軌道時自動移除號誌: {STRING} +STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT :自動移除軌道鋪設路徑上的號誌。請注意:本設定有導致火車事故的潛在風險 +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_VAL :{NUM}% 正常遊戲速度 ###setting-zero-is-special STR_CONFIG_SETTING_SOUND_TICKER :新聞提示: {STRING} @@ -1649,6 +1689,7 @@ STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT :當對手設立 STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :事故/災難: {STRING} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :當事故或災難發生時顯示報紙訊息 +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER_HELPTEXT :顯示有關對手公司事故運具的報紙 STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :公司資訊: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :當一所公司開始營業或倒閉破產時顯示報紙訊息 @@ -1700,10 +1741,12 @@ STR_CONFIG_SETTING_ENDING_YEAR_ZERO :永不 ###length 3 STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL :原版 +STR_CONFIG_SETTING_ECONOMY_TYPE_SMOOTH :平滑 STR_CONFIG_SETTING_ALLOW_SHARES :允許購買其它公司的股票:{STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :啟用此選項以容許公司買賣股票。一所公司必須達到一定的年齡方能買賣股票 +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :設定容許公司買賣股票的最小年齡 STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :轉運服務所得的收入百分比: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :設定進行轉運的運輸工具在卸載被轉運的貨物時,獲得的收入佔貨物總收入的百分比。此選項讓玩家更有效地控制收入分配方式 @@ -1718,10 +1761,10 @@ STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :自動在指定 STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :設定使用燈號號誌的年份。在遊戲進行到那一年之前,系統會預設豎立懸臂號誌 STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :按住 Ctrl 點選號誌時要切換的號誌種類:{STRING} -STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :選擇可透過 Ctrl+單撳 更換的號誌類型 +STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :選擇可透過 Ctrl+點擊 更換的號誌類型 ###length 2 STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :僅限路徑號誌 -STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :所有號誌 +STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :所有可見的號誌 ###length 2 STR_CONFIG_SETTING_SIGNAL_GUI_MODE_PATH :僅限路徑號誌 @@ -1750,11 +1793,13 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :禁止 STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :允許 STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :允許,可自訂市鎮道路配置 +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :貨物的產出速度取決於城市中的房屋,與城市的總人口數相關。{}二次方: 兩倍人口的都市產出四倍量的貨物{}線性: 兩倍人口的都市產出兩倍量的貨物 ###length 2 STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :遊戲中產生樹木的地點:{STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :控制遊戲內是否隨意種植樹木。此選項可能會影響一些依賴樹木的工業 (例如熱帶氣候的伐木場) ###length 4 +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_ALL :在任意地點皆可生長與擴散 STR_CONFIG_SETTING_TOOLBAR_POS :主工具列位置:{STRING} STR_CONFIG_SETTING_TOOLBAR_POS_HELPTEXT :設定主工具列在螢幕頂部的位置 @@ -1897,6 +1942,7 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}工業 STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}貨物分配 STR_CONFIG_SETTING_AI :{ORANGE}競爭對手 STR_CONFIG_SETTING_AI_NPC :{ORANGE}電腦玩家 +STR_CONFIG_SETTING_NETWORK :{ORANGE}網路 STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS :列車的路徑搜尋方式:{STRING} STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS_HELPTEXT :設定列車使用的路徑搜尋方式 @@ -1933,6 +1979,7 @@ STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}記憶 STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}無法編配{BYTES}作為子畫面快取。子畫面快取的大小已降至{BYTES}。OpenTTD的效能會受到影響。請嘗試停用32bpp圖形及/或減少放大倍數,以減低記憶體要求 # Video initalization errors +STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}...找不到相容的顯示卡裝置,硬體加速已被停用 # Intro window STR_INTRO_CAPTION :{WHITE}OpenTTD {REV} @@ -1976,6 +2023,7 @@ STR_INTRO_TRANSLATION :{BLACK}此段 # Quit window STR_QUIT_CAPTION :{WHITE}離開 +STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD :{YELLOW}您確定要關閉OperTTD嗎? STR_QUIT_YES :{BLACK}是 STR_QUIT_NO :{BLACK}否 @@ -1987,6 +2035,7 @@ STR_ABANDON_SCENARIO_QUERY :{YELLOW}你確 # Cheat window STR_CHEATS :{WHITE}作弊 STR_CHEATS_TOOLTIP :{BLACK}方塊被勾選代表您用過這個密技 +STR_CHEATS_NOTE :{BLACK}請注意:任何修改這些設定的操作將會被記錄於遊戲存檔中 STR_CHEAT_MONEY :{LTBLUE}增加金錢:{CURRENCY_LONG} STR_CHEAT_CHANGE_COMPANY :{LTBLUE}切換玩家操控的公司:{ORANGE}{COMMA} STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}神奇推土機 (可摧毀工業、無法移除的物件):{ORANGE}{STRING} @@ -2101,6 +2150,7 @@ STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}改變 # Matches ServerGameType ###length 3 +STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :僅限邀請加入 # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}多人遊戲 @@ -2137,6 +2187,7 @@ STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}遊戲 STR_NETWORK_SERVER_LIST_PASSWORD :{SILVER}受密碼保護! STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}伺服器離線 STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}伺服器已滿 +STR_NETWORK_SERVER_LIST_SERVER_TOO_OLD :{SILVER}伺服器太舊 STR_NETWORK_SERVER_LIST_VERSION_MISMATCH :{SILVER}版本不符 STR_NETWORK_SERVER_LIST_GRF_MISMATCH :{SILVER}NEWGRF 不符合 @@ -2152,6 +2203,7 @@ STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}起動 STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}起動您自己的伺服器 STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}輸入您的名稱 +STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}輸入伺服器位址或邀請碼 # Start new multiplayer server STR_NETWORK_START_SERVER_CAPTION :{WHITE}開始新的多人遊戲 @@ -2161,6 +2213,7 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}遊戲 STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}設定密碼 STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}如果您不想讓大眾連線的話,可以用密碼保護遊戲 +STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}可見性 STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} 玩家 STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}用戶端上限: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}選擇連線人數上限,但不是每個名額都要有人連線 @@ -2194,20 +2247,40 @@ STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}公司 # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :用戶端清單 +STR_NETWORK_COMPANY_LIST_SPECTATE :旁觀 # Network client list STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}多人遊戲 STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}伺服器 +STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}名稱 STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :伺服器名稱 STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}可見性 +STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}其他玩家可使用以進入伺服器的邀請碼 +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}連線類型 +STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}名稱 +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}編輯玩家名稱 +STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}加入此公司 +STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}傳送訊息給此玩家 +STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}傳送訊息給所有旁觀者 +STR_NETWORK_CLIENT_LIST_SPECTATORS :旁觀者 +STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}創立並加入一個新公司 # Matches ConnectionType ###length 5 +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}遠端玩家無法連線 +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}公開 STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :踢出 +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :停權 +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :密碼解鎖 +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}你確定要踢出玩家: '{STRING}'嗎? STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}你確定要刪除「{COMPANY}」公司嗎? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}你確定要重設 '{COMPANY}'的公司密碼嗎? +STR_NETWORK_ASK_RELAY_CAPTION :{WHITE}是否使用中繼伺服器? +STR_NETWORK_ASK_RELAY_NO :{BLACK}否 +STR_NETWORK_ASK_RELAY_YES_ONCE :{BLACK}是,僅此一次 STR_NETWORK_SPECTATORS :旁觀者 @@ -2236,6 +2309,7 @@ STR_NETWORK_CHAT_TO_COMPANY :[團隊] 給 {S STR_NETWORK_CHAT_CLIENT :[私人] {STRING}:{WHITE}{STRING} STR_NETWORK_CHAT_TO_CLIENT :[私人] 給 {STRING}:{WHITE}{STRING} STR_NETWORK_CHAT_ALL :[全員] {STRING}:{WHITE}{STRING} +STR_NETWORK_CHAT_EXTERNAL :[{3:STRING}] {0:STRING}: {WHITE}{1:STRING} STR_NETWORK_CHAT_OSKTITLE :{BLACK}輸入要聊天的文字 # Network messages @@ -2259,6 +2333,7 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}你輸 STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}您的電腦可能較慢,未能跟上伺服器的速度 STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}您的電腦花了太多時間下載地圖 STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}您的電腦花了太多時間嘗試加入這個伺服器 +STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}你的玩家名稱是無效的 STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}可能發生連線中斷 STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION :{WHITE}最後 {NUM} 秒沒有資料從伺服器過來 @@ -2284,6 +2359,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :未能及時取 STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :一般逾時狀況 STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :下載地圖需時太長 STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :處理地圖需時太長 +STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :無效的使用者端名稱 # Network related errors STR_NETWORK_SERVER_MESSAGE :*** {1:STRING} @@ -2309,10 +2385,15 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} 已建立新公司 (#{2:NUM}) STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} 已離開遊戲 ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} 已修改其名稱為 {STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} 付給{1:STRING} {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}伺服器關閉連線 STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}伺服器重新啟動中...{}請稍候... STR_NETWORK_MESSAGE_KICKED :*** {STRING} 已被踢出。原因:({STRING}) +STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}伺服器註冊失敗 +STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE :{WHITE}已有另一個伺服器以同樣的邀請碼進行註冊。點擊"本地"以改變遊戲模式 +STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}你的伺服器不接受遠端連線 +STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}其他玩家將無法連線到你的伺服器 # Content downloading window STR_CONTENT_TITLE :{WHITE}內容下載中 @@ -2410,6 +2491,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}貨物 STR_LINKGRAPH_LEGEND_ALL :{BLACK}全部 STR_LINKGRAPH_LEGEND_NONE :{BLACK}無 STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}選擇所顯示的公司 +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}未使用 @@ -2628,6 +2710,8 @@ STR_TREES_RANDOM_TYPE :{BLACK}隨機 STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}種植隨機種類樹木。按 Shift 可切換種植/顯示預估的種植費用 STR_TREES_RANDOM_TREES_BUTTON :{BLACK}隨機樹種 STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}在場景中隨機植樹 +STR_TREES_MODE_NORMAL_BUTTON :{BLACK}正常 +STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}框選一片區域以種植小規模的森林 STR_TREES_MODE_FOREST_LG_BUTTON :{BLACK}森林 # Land generation window (SE) @@ -2681,11 +2765,15 @@ STR_FUND_INDUSTRY_CAPTION :{WHITE}投資 STR_FUND_INDUSTRY_SELECTION_TOOLTIP :{BLACK}從清單中選擇合適的工業 STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES :隨機產生多個工業 STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP :{BLACK}以隨機分佈的工業佈滿地圖 +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION :{WHITE}隨機產生工業 STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_QUERY :{YELLOW}你確定要新建大量隨機工業嗎? STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST :{BLACK}費用:{YELLOW}{CURRENCY_LONG} STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK}探勘 STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY :{BLACK}設立 STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY :{BLACK}設立 +STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES :{BLACK}移除所有工業 +STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_TOOLTIP :{BLACK}移除地圖上所有工業 +STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_CAPTION :{WHITE}移除所有工業 # Industry cargoes window STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION :{WHITE}{STRING} 工業的產業鍊 @@ -2726,8 +2814,11 @@ STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}機場 STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF:{LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}接收貨物:{LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) +STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}鐵軌種類: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}道路類型: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}軌道速限:{LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}道路速限:{LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}有軌電車速限: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :石頭 @@ -2828,18 +2919,28 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD # Framerate display window STR_FRAMERATE_CAPTION :{WHITE}幀率 +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}模擬速度: {STRING} +STR_FRAMERATE_RATE_BLITTER :{BLACK}畫面幀數: {STRING} +STR_FRAMERATE_AVERAGE :{WHITE}平均 STR_FRAMERATE_MEMORYUSE :{WHITE}記憶體 STR_FRAMERATE_DATA_POINTS :{BLACK}數據基於 {COMMA} 個採樣 STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} 毫秒 +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} 幀/秒 +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} 幀/秒 STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} ###length 15 +STR_FRAMERATE_VIDEO :{BLACK}影像輸出 +STR_FRAMERATE_SOUND :{BLACK}混音: STR_FRAMERATE_GAMESCRIPT :{BLACK} 遊戲腳本: STR_FRAMERATE_AI :{BLACK} AI {NUM} {STRING} ###length 15 STR_FRAMETIME_CAPTION_GL_LANDSCAPE :世界刻 +STR_FRAMETIME_CAPTION_DRAWING :圖形彩現 STR_FRAMETIME_CAPTION_ALLSCRIPTS :GS/AI 腳本總計 +STR_FRAMETIME_CAPTION_GAMESCRIPT :遊戲腳本 STR_FRAMETIME_CAPTION_AI :AI {NUM} {STRING} @@ -2865,6 +2966,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}遊戲 STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}沒有可用的資訊 STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF:{WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}篩選字串: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}覆蓋檔案 STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}你確定要覆蓋現有存檔嗎? STR_SAVELOAD_DIRECTORY :{STRING} (路徑) @@ -2879,7 +2981,10 @@ STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}市鎮數量: STR_MAPGEN_DATE :{BLACK}日期: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}工業數量: +STR_MAPGEN_SNOW_COVERAGE :{BLACK}雪地覆蓋率: +STR_MAPGEN_SNOW_COVERAGE_UP :{BLACK}將雪地覆蓋率提高10% STR_MAPGEN_SNOW_COVERAGE_TEXT :{BLACK}{NUM}% +STR_MAPGEN_DESERT_COVERAGE :{BLACK}沙漠覆蓋率: STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}將沙漠覆蓋率提高10% STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% STR_MAPGEN_LAND_GENERATOR :{BLACK}地形產生器: @@ -2907,6 +3012,7 @@ STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}高度 STR_MAPGEN_HEIGHTMAP_SIZE_LABEL :{BLACK}大小: STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM} x {NUM} +STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT :{WHITE}沙漠覆蓋率 (以百分比%計算) STR_MAPGEN_START_DATE_QUERY_CAPT :{WHITE}修改開始年份 # SE Map generation @@ -3041,6 +3147,7 @@ STR_NEWGRF_ERROR_MSG_WARNING :{RED}警告:{ STR_NEWGRF_ERROR_MSG_ERROR :{RED}錯誤:{SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}嚴重錯誤:{SILVER}{STRING} STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}發生嚴重 NewGRF 錯誤的處理方式:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}發生NewGRF錯誤:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} 跟由 OpenTTD 回報的 TTDPatch 版本不合 STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} 只適合用於 TTD 版本 {STRING} STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} 必須跟 {STRING} 一起使用 @@ -3132,6 +3239,7 @@ STR_TOWN_POPULATION :{BLACK}世界 STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (城市) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}人口:{ORANGE}{COMMA}{BLACK} 房屋:{ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} 上月: {ORANGE}{COMMA}{BLACK} 最多: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}市鎮成長所需貨物: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED}需要 {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} 必須是冬天 @@ -3186,7 +3294,10 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}冒著 # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} 遊戲目標 STR_GOALS_SPECTATOR_CAPTION :{WHITE}全局目標 +STR_GOALS_SPECTATOR :全局目標 +STR_GOALS_GLOBAL_BUTTON :{BLACK}全局 STR_GOALS_GLOBAL_BUTTON_HELPTEXT :{BLACK}顯示全局目標 +STR_GOALS_COMPANY_BUTTON :{BLACK}公司 STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- 當前無目標 - STR_GOALS_PROGRESS :{ORANGE}{STRING} @@ -3194,10 +3305,10 @@ STR_GOALS_PROGRESS_COMPLETE :{GREEN}{STRING} STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}點選目標以將有關工業 / 市鎮或方格置於畫面中央。按下 Ctrl 鍵並點選目標以開啟一個以有關工業 / 市鎮或方格為中心的新視野 # Goal question window -STR_GOAL_QUESTION_CAPTION_QUESTION :問題 -STR_GOAL_QUESTION_CAPTION_INFORMATION :資訊 -STR_GOAL_QUESTION_CAPTION_WARNING :警告 -STR_GOAL_QUESTION_CAPTION_ERROR :錯誤 +STR_GOAL_QUESTION_CAPTION_QUESTION :{BLACK}問題 +STR_GOAL_QUESTION_CAPTION_INFORMATION :{BLACK}資訊 +STR_GOAL_QUESTION_CAPTION_WARNING :{BLACK}警告 +STR_GOAL_QUESTION_CAPTION_ERROR :{YELLOW}錯誤 # Goal Question button list ###length 18 @@ -3423,9 +3534,12 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}每年{C # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}工業 STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- 無 - +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} (運送了{COMMA}%){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}工業名稱 - 點選名稱可將工業置於畫面中央。 按住 Ctrl 點選可於工業位置開啟新視窗視野 +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}接受貨物: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :所有貨物種類 STR_INDUSTRY_DIRECTORY_FILTER_NONE :無 @@ -3440,6 +3554,8 @@ STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}該工 STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}需要: {YELLOW}{STRING}{STRING} STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :,{STRING}{STRING} +STR_INDUSTRY_VIEW_REQUIRES :{BLACK}需要: +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}修改產量 (以 8 為倍數增減,最大為 2040) STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}變更產出等級 (百分比,最高可到800%) @@ -3493,12 +3609,13 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :未分組的車 STR_GROUP_DEFAULT_SHIPS :未分組的船舶 STR_GROUP_DEFAULT_AIRCRAFTS :未分組的飛機 +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}群組 - 點選群組以顯示其中的運輸工具清單。拖曳群組標籤以排列群組的次序和層級。 STR_GROUP_CREATE_TOOLTIP :{BLACK}點選可建立群組 STR_GROUP_DELETE_TOOLTIP :{BLACK}移除所選群組 STR_GROUP_RENAME_TOOLTIP :{BLACK}重新命名群組 -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}點選可保護此群組排除在全域自動替換設定之外 +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}點選可保護此群組排除在全域自動替換設定之外。按住 Ctrl 鍵點選以套用至所有子群組 STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}刪除群組 STR_GROUP_DELETE_QUERY_TEXT :{WHITE}您是否決定刪除此群組及其所有子群組? @@ -3509,6 +3626,9 @@ STR_GROUP_REMOVE_ALL_VEHICLES :移去所有運 STR_GROUP_RENAME_CAPTION :{BLACK}重新命名群組 STR_GROUP_PROFIT_THIS_YEAR :今年盈利: +STR_GROUP_PROFIT_LAST_YEAR :去年盈利: +STR_GROUP_OCCUPANCY :目前使用率: +STR_GROUP_OCCUPANCY_VALUE :{NUM}% # Build vehicle window ###length 4 @@ -3518,10 +3638,12 @@ STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :新購單軌車 STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :新購磁浮車輛 STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :新購車輛 +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :新的電車運具 # Vehicle availability ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :新購鐵路列車 +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :新購車輛 STR_BUY_VEHICLE_SHIP_CAPTION :新購船舶 STR_BUY_VEHICLE_AIRCRAFT_CAPTION :新購飛機 @@ -3537,12 +3659,15 @@ STR_PURCHASE_INFO_REFITTABLE :(可改裝) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}設計年份:{GOLD}{NUM}{BLACK} 使用年限:{GOLD}{COMMA} 年 STR_PURCHASE_INFO_RELIABILITY :{BLACK}最大可靠度:{GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}費用:{GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}費用: {GOLD}{CURRENCY_LONG}{BLACK} (改裝費用: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}載重:{GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}費用:{GOLD}{CURRENCY_LONG}{BLACK} 速度:{GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}費用: {GOLD}{CURRENCY_LONG}{BLACK} (改裝費用: {GOLD}{CURRENCY_LONG}{BLACK}) 速度: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}容量:{GOLD}{CARGO_LONG},{CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}動力車廂:{GOLD}+{POWER}{BLACK} 載重:{GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}可改裝成:{GOLD}{STRING} STR_PURCHASE_INFO_ALL_TYPES :所有貨物種類 +STR_PURCHASE_INFO_NONE :無 STR_PURCHASE_INFO_ALL_BUT :所有貨物({CARGO_LIST}除外) STR_PURCHASE_INFO_MAX_TE :{BLACK}最大牽引力:{GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}範圍: {GOLD}{COMMA} 方格 @@ -3571,6 +3696,8 @@ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}購買 STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}購買選定的飛機。按住 Shift 點選則只會顯示預估的購買費用 ###length VEHICLE_TYPES +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}購買並改裝選定的車輛。按住 Shift 點選則只會顯示預估的購買費用 +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}購買並改裝選定的船舶。按住 Shift 點選則只會顯示預估的購買費用 STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}購買並改裝選定的飛機。按住 Shift 點選則只會顯示預估的購買費用 ###length VEHICLE_TYPES @@ -3704,6 +3831,7 @@ STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :單軌機車頭 STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :磁浮機車頭 STR_ENGINE_PREVIEW_ROAD_VEHICLE :車輛 +STR_ENGINE_PREVIEW_TRAM_VEHICLE :有軌電車運具 STR_ENGINE_PREVIEW_AIRCRAFT :飛機 STR_ENGINE_PREVIEW_SHIP :船舶 @@ -3711,6 +3839,8 @@ STR_ENGINE_PREVIEW_SHIP :船舶 STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}費用:{CURRENCY_LONG} 載重:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER}{}營運成本:{CURRENCY_LONG} / 年{}容量:{CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}費用:{CURRENCY_LONG} 載重:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER} 最大牽引力:{6:FORCE}{}營運成本:{4:CURRENCY_LONG}/年{}容量:{5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}費用:{CURRENCY_LONG} 最高速度:{VELOCITY}{}容量:{CARGO_LONG}{}營運成本:{CURRENCY_LONG}/年 +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}費用: {CURRENCY_LONG} 最高速度: {VELOCITY}{}航空運具型號: {STRING}{}容量: {CARGO_LONG}{}營運成本: {CURRENCY_LONG}/年 +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}費用: {CURRENCY_LONG} 最高速度: {VELOCITY}{}航空運具型號: {STRING} 距離: {COMMA} 格{}容量: {CARGO_LONG}, {CARGO_LONG}{}營運成本: {CURRENCY_LONG}/年 # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}替換 {STRING} - {STRING} @@ -3742,6 +3872,7 @@ STR_REPLACE_HELP_STOP_BUTTON :{BLACK}按下 STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}在車頭及車廂替換畫面間切換。 STR_REPLACE_ENGINES :車頭 STR_REPLACE_WAGONS :車廂 +STR_REPLACE_ALL_RAILTYPE :所有的軌道運具 STR_REPLACE_ALL_ROADTYPE :所有公路車輛 ###length 2 @@ -3755,13 +3886,17 @@ STR_REPLACE_MONORAIL_VEHICLES :單軌列車 STR_REPLACE_MAGLEV_VEHICLES :磁浮列車 STR_REPLACE_ROAD_VEHICLES :車輛 +STR_REPLACE_TRAM_VEHICLES :有軌電車運具 +STR_REPLACE_REMOVE_WAGON :{BLACK}移除車廂({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}如果替換後的車廂較長的話,讓自動替換功能移除多餘的車廂 (從頭開始) 以便維持列車長度 +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. 按住Ctrl並點擊以套用到所有子群組 # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} ###length VEHICLE_TYPES +STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}將飛機置於畫面中央。雙擊將會使視野跟隨飛機。 按住 Ctrl 點選可於飛機位置開啟新視窗視野 ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}將列車送回機廠,按住 CTRL 點選機廠則僅做維護 @@ -3798,6 +3933,9 @@ STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}顯示 STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}顯示飛機詳細資料 ###length VEHICLE_TYPES +STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}目前列車狀態 - 點擊以停止/起動運具 +STR_VEHICLE_VIEW_ROAD_VEHICLE_STATUS_START_STOP_TOOLTIP :{BLACK}目前列車狀態 - 點擊以停止/起動運具 +STR_VEHICLE_VIEW_SHIP_STATE_STATUS_STOP_TOOLTIP :{BLACK}目前船舶狀態 - 點擊以停止/起動運具 # Messages in the start stop button in the vehicle view STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}正在裝卸貨物 @@ -3842,6 +3980,8 @@ STR_VEHICLE_INFO_AGE :{COMMA} 年 ({C STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} 年 ({COMMA}) STR_VEHICLE_INFO_MAX_SPEED :{BLACK}最高速度:{LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}最大速度: {LTBLUE}{VELOCITY} {BLACK}空中運具型號: {LTBLUE}{STRING} +STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}最高速度: {LTBLUE}{VELOCITY} {BLACK}航空運具型號: {LTBLUE}{STRING} {BLACK}距離: {LTBLUE}{COMMA} 格 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}載重:{LTBLUE}{WEIGHT_SHORT} {BLACK}功率:{LTBLUE}{POWER}{BLACK} 最高速度:{LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}載重:{LTBLUE}{WEIGHT_SHORT} {BLACK}功率:{LTBLUE}{POWER}{BLACK} 最高速度:{LTBLUE}{VELOCITY} {BLACK}最大牽引力:{LTBLUE}{FORCE} @@ -3980,6 +4120,7 @@ STR_ORDER_CONDITIONAL_AGE :年齡 (年) STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :需要維護 STR_ORDER_CONDITIONAL_UNCONDITIONALLY :總是 STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :剩餘年限 (年) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :最大可靠度 ###next-name-looks-similar STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}運輸工具相關數字與指定數值比對的條件 @@ -4215,6 +4356,8 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}選擇 STR_AI_LIST_CANCEL :{BLACK}取消 STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}不改變腳本 +STR_SCREENSHOT_CAPTION :{WHITE}螢幕截圖 +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}截圖整張地圖 # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} 參數 @@ -4275,6 +4418,7 @@ STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :該存檔是由 STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE :檔案無法讀取 STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE :檔案無法寫入 STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED :資料完整性檢查失敗 +STR_GAME_SAVELOAD_ERROR_PATCHPACK :該存檔是由被修改過的遊戲所產生 STR_GAME_SAVELOAD_NOT_AVAILABLE :<無法使用> STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}此存檔版本不支援路面電車,已移除所有路面電車 @@ -4481,6 +4625,7 @@ STR_ERROR_DEPOT_WRONG_DEPOT_TYPE :錯誤的機廠 STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}{VEHICLE} 將在替換後過長 STR_ERROR_AUTOREPLACE_NOTHING_TO_DO :{WHITE}無自動替換/翻新的規則可套用 STR_ERROR_AUTOREPLACE_MONEY_LIMIT :(金錢限制) +STR_ERROR_AUTOREPLACE_INCOMPATIBLE_CARGO :{WHITE}新的運具無法運輸 {STRING} # Rail construction errors STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}不合理的軌道組合 @@ -4508,6 +4653,9 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}不能 STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}無法移除此處的電車軌... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... 這裡沒有道路 STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... 這裡沒有電車軌 +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}無法轉換此處的道路類型... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}沒有適合的道路 +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}沒有合適的電車軌道 # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}無法在此興建運河... @@ -4682,6 +4830,7 @@ STR_BASESOUNDS_DOS_DESCRIPTION :原版 Transpor STR_BASESOUNDS_WIN_DESCRIPTION :原版 Transport Tycoon Deluxe Windows 版的音效。 STR_BASESOUNDS_NONE_DESCRIPTION :不含任何音效的音效集。 STR_BASEMUSIC_WIN_DESCRIPTION :原版 Transport Tycoon Deluxe Windows 版的音樂。 +STR_BASEMUSIC_DOS_DESCRIPTION :原版 Transport Tycoon Deluxe DOS 版的音樂。 STR_BASEMUSIC_NONE_DESCRIPTION :不含任何音樂的音樂集。 ##id 0x2000 @@ -5078,6 +5227,7 @@ STR_FORMAT_DATE_ISO :{2:NUM}-{1:STRI STR_FORMAT_COMPANY_NUM :(公司 {COMMA}) STR_FORMAT_GROUP_NAME :群組 {COMMA} +STR_FORMAT_GROUP_VEHICLE_NAME :{GROUP} #{COMMA} STR_FORMAT_INDUSTRY_NAME :{TOWN} {STRING} ###length 2 From 39e8783f4b8d24a27d28f99905acf8f54dec24fa Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Thu, 28 Oct 2021 23:10:03 +0200 Subject: [PATCH 02/60] Fix: Template syntax error when using 'span' with a container type. --- src/core/CMakeLists.txt | 1 + src/core/span_type.hpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 96da089326..b94ed77e91 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -26,5 +26,6 @@ add_files( smallmatrix_type.hpp smallstack_type.hpp smallvec_type.hpp + span_type.hpp string_compare_type.hpp ) diff --git a/src/core/span_type.hpp b/src/core/span_type.hpp index 03bc678b7e..614be84567 100644 --- a/src/core/span_type.hpp +++ b/src/core/span_type.hpp @@ -31,8 +31,8 @@ struct is_compatible_element < C, E, std::void_t< decltype(std::data(std::declval())), - typename std::remove_pointer()))>::type(*)[]> -> : std::is_convertible()))>::type(*)[], E(*)[]>{}; + typename std::remove_pointer_t()))>(*)[]> +> : std::is_convertible()))>(*)[], E(*)[]>{}; /* Template to check if a container is compatible. gsl-lite also includes is_array and is_std_array, but as we don't use them, they are omitted. */ template From b6933a2ebdf66c5fb23b2226d3ce07d71426d7d2 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 3 Oct 2021 15:39:49 +0200 Subject: [PATCH 03/60] Codechange: Move command arguments to the back of the DoCommand function call. --- src/aircraft_cmd.cpp | 6 ++-- src/autoreplace_cmd.cpp | 28 +++++++++---------- src/bridge_gui.cpp | 2 +- src/build_vehicle_gui.cpp | 2 +- src/clear_cmd.cpp | 2 +- src/command.cpp | 8 +++--- src/command_func.h | 2 +- src/company_cmd.cpp | 2 +- src/disaster_vehicle.cpp | 4 +-- src/economy.cpp | 10 +++---- src/group_cmd.cpp | 8 +++--- src/industry_cmd.cpp | 14 +++++----- src/landscape.cpp | 4 +-- src/misc_gui.cpp | 2 +- src/object_cmd.cpp | 12 ++++---- src/order_backup.cpp | 4 +-- src/order_cmd.cpp | 2 +- src/rail_cmd.cpp | 24 ++++++++-------- src/rail_gui.cpp | 2 +- src/road_cmd.cpp | 20 +++++++------- src/road_gui.cpp | 2 +- src/roadveh_cmd.cpp | 2 +- src/script/api/script_vehicle.cpp | 4 +-- src/station_cmd.cpp | 22 +++++++-------- src/terraform_cmd.cpp | 6 ++-- src/terraform_gui.cpp | 2 +- src/town_cmd.cpp | 46 +++++++++++++++---------------- src/train_cmd.cpp | 6 ++-- src/tree_cmd.cpp | 4 +-- src/tunnelbridge_cmd.cpp | 16 +++++------ src/vehicle.cpp | 8 +++--- src/vehicle_cmd.cpp | 30 ++++++++++---------- src/vehicle_gui.cpp | 4 +-- src/water_cmd.cpp | 22 +++++++-------- src/waypoint_cmd.cpp | 2 +- 35 files changed, 167 insertions(+), 167 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 4c4ed5a46a..1f52bbecd2 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1274,7 +1274,7 @@ void HandleMissingAircraftOrders(Aircraft *v) const Station *st = GetTargetAirportIfValid(v); if (st == nullptr) { Backup cur_company(_current_company, v->owner, FILE_LINE); - CommandCost ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT); + CommandCost ret = DoCommand(DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT, v->tile, v->index, 0); cur_company.Restore(); if (ret.Failed()) CrashAirplane(v); @@ -1637,7 +1637,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass /* Send the helicopter to a hangar if needed for replacement */ if (v->NeedsAutomaticServicing()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - DoCommand(v->tile, v->index | DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, 0, DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT); + DoCommand(DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT, v->tile, v->index | DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, 0); cur_company.Restore(); } } @@ -1688,7 +1688,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc /* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */ if (v->NeedsAutomaticServicing()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - DoCommand(v->tile, v->index | DEPOT_SERVICE, 0, DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT); + DoCommand(DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT, v->tile, v->index | DEPOT_SERVICE, 0); cur_company.Restore(); } } diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 4f9cf92bb4..617c3bc6c1 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -340,7 +340,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic } /* Build the new vehicle */ - cost = DoCommand(old_veh->tile, e | (CT_INVALID << 24), 0, DC_EXEC | DC_AUTOREPLACE, GetCmdBuildVeh(old_veh)); + cost = DoCommand(DC_EXEC | DC_AUTOREPLACE, GetCmdBuildVeh(old_veh), old_veh->tile, e | (CT_INVALID << 24), 0); if (cost.Failed()) return cost; Vehicle *new_veh = Vehicle::Get(_new_vehicle_id); @@ -350,13 +350,13 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic if (refit_cargo != CT_NO_REFIT) { byte subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo); - cost.AddCost(DoCommand(0, new_veh->index, refit_cargo | (subtype << 8), DC_EXEC, GetCmdRefitVeh(new_veh))); + cost.AddCost(DoCommand(DC_EXEC, GetCmdRefitVeh(new_veh), 0, new_veh->index, refit_cargo | (subtype << 8))); assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace() } /* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */ if (new_veh->type == VEH_TRAIN && HasBit(Train::From(old_veh)->flags, VRF_REVERSE_DIRECTION)) { - DoCommand(0, new_veh->index, true, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); + DoCommand(DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION, 0, new_veh->index, true); } return cost; @@ -370,7 +370,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic */ static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_callback) { - return DoCommand(0, v->index, evaluate_callback ? 1 : 0, DC_EXEC | DC_AUTOREPLACE, CMD_START_STOP_VEHICLE); + return DoCommand(DC_EXEC | DC_AUTOREPLACE, CMD_START_STOP_VEHICLE, 0, v->index, evaluate_callback ? 1 : 0); } /** @@ -383,7 +383,7 @@ static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_ca */ static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlag flags, bool whole_chain) { - return DoCommand(0, v->index | (whole_chain ? 1 : 0) << 20, after != nullptr ? after->index : INVALID_VEHICLE, flags | DC_NO_CARGO_CAP_CHECK, CMD_MOVE_RAIL_VEHICLE); + return DoCommand(flags | DC_NO_CARGO_CAP_CHECK, CMD_MOVE_RAIL_VEHICLE, 0, v->index | (whole_chain ? 1 : 0) << 20, after != nullptr ? after->index : INVALID_VEHICLE); } /** @@ -397,10 +397,10 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, CommandCost cost = CommandCost(); /* Share orders */ - if (cost.Succeeded() && old_head != new_head) cost.AddCost(DoCommand(0, new_head->index | CO_SHARE << 30, old_head->index, DC_EXEC, CMD_CLONE_ORDER)); + if (cost.Succeeded() && old_head != new_head) cost.AddCost(DoCommand(DC_EXEC, CMD_CLONE_ORDER, 0, new_head->index | CO_SHARE << 30, old_head->index)); /* Copy group membership */ - if (cost.Succeeded() && old_head != new_head) cost.AddCost(DoCommand(0, old_head->group_id, new_head->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP)); + if (cost.Succeeded() && old_head != new_head) cost.AddCost(DoCommand(DC_EXEC, CMD_ADD_VEHICLE_GROUP, 0, old_head->group_id, new_head->index)); /* Perform start/stop check whether the new vehicle suits newgrf restrictions etc. */ if (cost.Succeeded()) { @@ -466,11 +466,11 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b } /* Sell the old vehicle */ - cost.AddCost(DoCommand(0, old_v->index, 0, flags, GetCmdSellVeh(old_v))); + cost.AddCost(DoCommand(flags, GetCmdSellVeh(old_v), 0, old_v->index, 0)); /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - DoCommand(0, new_v->index, 0, DC_EXEC, GetCmdSellVeh(new_v)); + DoCommand(DC_EXEC, GetCmdSellVeh(new_v), 0, new_v->index, 0); } } @@ -597,7 +597,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON); /* Sell wagon */ - [[maybe_unused]] CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon)); + [[maybe_unused]] CommandCost ret = DoCommand(DC_EXEC, GetCmdSellVeh(wagon), 0, wagon->index, 0); assert(ret.Succeeded()); new_vehs[i] = nullptr; @@ -629,7 +629,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Sell the vehicle. * Note: This might temporarily construct new trains, so use DC_AUTOREPLACE to prevent * it from failing due to engine limits. */ - cost.AddCost(DoCommand(0, w->index, 0, flags | DC_AUTOREPLACE, GetCmdSellVeh(w))); + cost.AddCost(DoCommand(flags | DC_AUTOREPLACE, GetCmdSellVeh(w), 0, w->index, 0)); if ((flags & DC_EXEC) != 0) { old_vehs[i] = nullptr; if (i == 0) old_head = nullptr; @@ -660,7 +660,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon if ((flags & DC_EXEC) == 0) { for (int i = num_units - 1; i >= 0; i--) { if (new_vehs[i] != nullptr) { - DoCommand(0, new_vehs[i]->index, 0, DC_EXEC, GetCmdSellVeh(new_vehs[i])); + DoCommand(DC_EXEC, GetCmdSellVeh(new_vehs[i]), 0, new_vehs[i]->index, 0); new_vehs[i] = nullptr; } } @@ -691,12 +691,12 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon } /* Sell the old vehicle */ - cost.AddCost(DoCommand(0, old_head->index, 0, flags, GetCmdSellVeh(old_head))); + cost.AddCost(DoCommand(flags, GetCmdSellVeh(old_head), 0, old_head->index, 0)); } /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - DoCommand(0, new_head->index, 0, DC_EXEC, GetCmdSellVeh(new_head)); + DoCommand(DC_EXEC, GetCmdSellVeh(new_head), 0, new_head->index, 0); } } } diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 74c7234d57..9e6fc4eeef 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -390,7 +390,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo /* only query bridge building possibility once, result is the same for all bridges! * returns CMD_ERROR on failure, and price on success */ StringID errmsg = INVALID_STRING_ID; - CommandCost ret = DoCommand(end, start, type, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)) | DC_QUERY_COST, CMD_BUILD_BRIDGE); + CommandCost ret = DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)) | DC_QUERY_COST, CMD_BUILD_BRIDGE, end, start, type); GUIBridgeList *bl = nullptr; if (ret.Failed()) { diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 547ac3e003..6bee767b0c 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1226,7 +1226,7 @@ struct BuildVehicleWindow : Window { if (!this->listview_mode) { /* Query for cost and refitted capacity */ - CommandCost ret = DoCommand(this->window_number, this->sel_engine | (cargo << 24), 0, DC_QUERY_COST, GetCmdBuildVeh(this->vehicle_type)); + CommandCost ret = DoCommand(DC_QUERY_COST, GetCmdBuildVeh(this->vehicle_type), this->window_number, this->sel_engine | (cargo << 24), 0); if (ret.Succeeded()) { this->te.cost = ret.GetCost() - e->GetCost(); this->te.capacity = _returned_refit_capacity; diff --git a/src/clear_cmd.cpp b/src/clear_cmd.cpp index 4036313123..918f5c373c 100644 --- a/src/clear_cmd.cpp +++ b/src/clear_cmd.cpp @@ -381,7 +381,7 @@ static void ChangeTileOwner_Clear(TileIndex tile, Owner old_owner, Owner new_own static CommandCost TerraformTile_Clear(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } extern const TileTypeProcs _tile_type_clear_procs = { diff --git a/src/command.cpp b/src/command.cpp index 7d1a72dec9..b971ccb6bd 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -449,23 +449,23 @@ static int _docommand_recursive = 0; */ CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags) { - return DoCommand(container->tile, container->p1, container->p2, flags, container->cmd & CMD_ID_MASK, container->text); + return DoCommand(flags, container->cmd & CMD_ID_MASK, container->tile, container->p1, container->p2, container->text); } /*! * This function executes a given command with the parameters from the #CommandProc parameter list. * Depending on the flags parameter it execute or test a command. * + * @param flags Flags for the command and how to execute the command + * @param cmd The command-id to execute (a value of the CMD_* enums) * @param tile The tile to apply the command on (for the #CommandProc) * @param p1 Additional data for the command (for the #CommandProc) * @param p2 Additional data for the command (for the #CommandProc) - * @param flags Flags for the command and how to execute the command - * @param cmd The command-id to execute (a value of the CMD_* enums) * @param text The text to pass * @see CommandProc * @return the cost */ -CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const std::string &text) +CommandCost DoCommand(DoCommandFlag flags, uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CommandCost res; diff --git a/src/command_func.h b/src/command_func.h index 426283bd3a..07de8de9c0 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -32,7 +32,7 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); */ #define return_cmd_error(errcode) return CommandCost(errcode); -CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const std::string &text = {}); +CommandCost DoCommand(DoCommandFlag flags, uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags); bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr, const std::string &text = {}, bool my_cmd = true); diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 7549212849..ce7488f037 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -1127,7 +1127,7 @@ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, u c->president_name = text; if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) { - DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, text + " Transport"); + DoCommand(DC_EXEC, CMD_RENAME_COMPANY, 0, 0, 0, text + " Transport"); } } diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index cc245b38fe..126e48f5fc 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -61,7 +61,7 @@ static void DisasterClearSquare(TileIndex tile) case MP_RAILWAY: if (Company::IsHumanID(GetTileOwner(tile)) && !IsRailDepot(tile)) { Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); - DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); + DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, tile, 0, 0); cur_company.Restore(); /* update signals in buffer */ @@ -71,7 +71,7 @@ static void DisasterClearSquare(TileIndex tile) case MP_HOUSE: { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); - DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); + DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, tile, 0, 0); cur_company.Restore(); break; } diff --git a/src/economy.cpp b/src/economy.cpp index 936fba7896..5c25636454 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -312,7 +312,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) for (i = 0; i < 4; i++) { if (c->share_owners[i] == old_owner) { /* Sell its shares */ - CommandCost res = DoCommand(0, c->index, 0, DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY); + CommandCost res = DoCommand(DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY, 0, c->index, 0); /* Because we are in a DoCommand, we can't just execute another one and * expect the money to be removed. We need to do it ourself! */ SubtractMoneyFromCompany(res); @@ -332,7 +332,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } else { cur_company2.Change(c->share_owners[i]); /* Sell the shares */ - CommandCost res = DoCommand(0, old_owner, 0, DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY); + CommandCost res = DoCommand(DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY, 0, old_owner, 0); /* Because we are in a DoCommand, we can't just execute another one and * expect the money to be removed. We need to do it ourself! */ SubtractMoneyFromCompany(res); @@ -448,7 +448,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) * However, do not rely on that behaviour. */ int interval = CompanyServiceInterval(new_company, v->type); - DoCommand(v->tile, v->index, interval | (new_company->settings.vehicle.servint_ispercent << 17), DC_EXEC | DC_BANKRUPT, CMD_CHANGE_SERVICE_INT); + DoCommand(DC_EXEC | DC_BANKRUPT, CMD_CHANGE_SERVICE_INT, v->tile, v->index, interval | (new_company->settings.vehicle.servint_ispercent << 17)); } v->owner = new_owner; @@ -1485,7 +1485,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station if (st->goods[cid].cargo.HasCargoFor(next_station)) { /* Try to find out if auto-refitting would succeed. In case the refit is allowed, * the returned refit capacity will be greater than zero. */ - DoCommand(v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16, DC_QUERY_COST, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts. + DoCommand(DC_QUERY_COST, GetCmdRefitVeh(v_start), v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16); // Auto-refit and only this vehicle including artic parts. /* Try to balance different loadable cargoes between parts of the consist, so that * all of them can be loaded. Avoid a situation where all vehicles suddenly switch * to the first loadable cargo for which there is only one packet. If the capacities @@ -1508,7 +1508,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station * "via any station" before reserving. We rather produce some more "any station" cargo than * misrouting it. */ IterateVehicleParts(v_start, ReturnCargoAction(st, INVALID_STATION)); - CommandCost cost = DoCommand(v_start->tile, v_start->index, new_cid | 1U << 24 | 0xFF << 8 | 1U << 16, DC_EXEC, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts. + CommandCost cost = DoCommand(DC_EXEC, GetCmdRefitVeh(v_start), v_start->tile, v_start->index, new_cid | 1U << 24 | 0xFF << 8 | 1U << 16); // Auto-refit and only this vehicle including artic parts. if (cost.Succeeded()) v->First()->profit_this_year -= cost.GetCost() << 8; } diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index 50b361d007..ec4358f765 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -356,12 +356,12 @@ CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (g == nullptr || g->owner != _current_company) return CMD_ERROR; /* Remove all vehicles from the group */ - DoCommand(0, p1, 0, flags, CMD_REMOVE_ALL_VEHICLES_GROUP); + DoCommand(flags, CMD_REMOVE_ALL_VEHICLES_GROUP, 0, p1, 0); /* Delete sub-groups */ for (const Group *gp : Group::Iterate()) { if (gp->parent == g->index) { - DoCommand(0, gp->index, 0, flags, CMD_DELETE_GROUP); + DoCommand(flags, CMD_DELETE_GROUP, 0, gp->index, 0); } } @@ -580,7 +580,7 @@ CommandCost CmdAddSharedVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 /* For each shared vehicles add it to the group */ for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { - if (v2->group_id != id_g) DoCommand(tile, id_g, v2->index, flags, CMD_ADD_VEHICLE_GROUP, text); + if (v2->group_id != id_g) DoCommand(flags, CMD_ADD_VEHICLE_GROUP, tile, id_g, v2->index, text); } } } @@ -616,7 +616,7 @@ CommandCost CmdRemoveAllVehiclesGroup(TileIndex tile, DoCommandFlag flags, uint3 if (v->group_id != old_g) continue; /* Add The Vehicle to the default group */ - DoCommand(tile, DEFAULT_GROUP, v->index, flags, CMD_ADD_VEHICLE_GROUP, text); + DoCommand(flags, CMD_ADD_VEHICLE_GROUP, tile, DEFAULT_GROUP, v->index, text); } } diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index b03a722b78..529e01edbe 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1100,7 +1100,7 @@ static bool SearchLumberMillTrees(TileIndex tile, void *user_data) _industry_sound_tile = tile; if (_settings_client.sound.ambient) SndPlayTileFx(SND_38_LUMBER_MILL_1, tile); - DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); + DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, tile, 0, 0); cur_company.Restore(); return true; @@ -1482,13 +1482,13 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */ Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); - CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(DC_NONE, CMD_LANDSCAPE_CLEAR, cur_tile, 0, 0); cur_company.Restore(); if (ret.Failed()) return ret; } else { /* Clear the tiles, but do not affect town ratings */ - CommandCost ret = DoCommand(cur_tile, 0, 0, DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR, cur_tile, 0, 0); if (ret.Failed()) return ret; } @@ -1598,7 +1598,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, } /* This is not 100% correct check, but the best we can do without modifying the map. * What is missing, is if the difference in height is more than 1.. */ - if (DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND).Failed()) { + if (DoCommand(flags & ~DC_EXEC, CMD_TERRAFORM_LAND, tile_walk, SLOPE_N, (curh > h) ? 0 : 1).Failed()) { cur_company.Restore(); return false; } @@ -1613,7 +1613,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, /* We give the terraforming for free here, because we can't calculate * exact cost in the test-round, and as we all know, that will cause * a nice assert if they don't match ;) */ - DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND); + DoCommand(flags, CMD_TERRAFORM_LAND, tile_walk, SLOPE_N, (curh > h) ? 0 : 1); curh += (curh > h) ? -1 : 1; } } @@ -1883,7 +1883,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID); - DoCommand(cur_tile, 0, 0, DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR); + DoCommand(DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR, cur_tile, 0, 0); MakeIndustry(cur_tile, i->index, it.gfx, Random(), wc); @@ -3059,7 +3059,7 @@ static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, i } } } - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } extern const TileTypeProcs _tile_type_industry_procs = { diff --git a/src/landscape.cpp b/src/landscape.cpp index f13d1835f7..242ee089ac 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -755,7 +755,7 @@ CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 TileIterator *iter = HasBit(p2, 0) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex t = *iter; - CommandCost ret = DoCommand(t, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR, t, 0, 0); if (ret.Failed()) { last_error = ret; @@ -772,7 +772,7 @@ CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 delete iter; return cost; } - DoCommand(t, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + DoCommand(flags, CMD_LANDSCAPE_CLEAR, t, 0, 0); /* draw explosion animation... * Disable explosions when game is paused. Looks silly and blocks the view. */ diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index f0492925d8..859798deb1 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -191,7 +191,7 @@ public: Company *c = Company::GetIfValid(_local_company); if (c != nullptr) { assert(_current_company == _local_company); - CommandCost costclear = DoCommand(tile, 0, 0, DC_QUERY_COST, CMD_LANDSCAPE_CLEAR); + CommandCost costclear = DoCommand(DC_QUERY_COST, CMD_LANDSCAPE_CLEAR, tile, 0, 0); if (costclear.Succeeded()) { Money cost = costclear.GetCost(); if (cost < 0) { diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 7e1e36c1f1..328cadd93d 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -229,7 +229,7 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (type == OBJECT_OWNED_LAND) { /* Owned land is special as it can be placed on any slope. */ - cost.AddCost(DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)); + cost.AddCost(DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0)); } else { /* Check the surface to build on. At this time we can't actually execute the * the CLEAR_TILE commands since the newgrf callback later on can check @@ -242,7 +242,7 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (!IsWaterTile(t)) { /* Normal water tiles don't have to be cleared. For all other tile types clear * the tile but leave the water. */ - cost.AddCost(DoCommand(t, 0, 0, flags & ~DC_NO_WATER & ~DC_EXEC, CMD_LANDSCAPE_CLEAR)); + cost.AddCost(DoCommand(flags & ~DC_NO_WATER & ~DC_EXEC, CMD_LANDSCAPE_CLEAR, t, 0, 0)); } else { /* Can't build on water owned by another company. */ Owner o = GetTileOwner(t); @@ -260,7 +260,7 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 IsTileType(t, MP_OBJECT) && IsTileOwner(t, _current_company) && IsObjectType(t, OBJECT_HQ))) { - cost.AddCost(DoCommand(t, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR)); + cost.AddCost(DoCommand(flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR, t, 0, 0)); } } } @@ -292,10 +292,10 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 for (TileIndex t : ta) { if (HasTileWaterGround(t)) { if (!IsWaterTile(t)) { - DoCommand(t, 0, 0, (flags & ~DC_NO_WATER) | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR); + DoCommand((flags & ~DC_NO_WATER) | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR, t, 0, 0); } } else { - DoCommand(t, 0, 0, flags | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR); + DoCommand(flags | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR, t, 0, 0); } } } @@ -847,7 +847,7 @@ static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlag flags, int } } - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } extern const TileTypeProcs _tile_type_object_procs = { diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 37579a3198..8b8c2685f6 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -73,7 +73,7 @@ void OrderBackup::DoRestore(Vehicle *v) { /* If we had shared orders, recover that */ if (this->clone != nullptr) { - DoCommand(0, v->index | CO_SHARE << 30, this->clone->index, DC_EXEC, CMD_CLONE_ORDER); + DoCommand(DC_EXEC, CMD_CLONE_ORDER, 0, v->index | CO_SHARE << 30, this->clone->index); } else if (this->orders != nullptr && OrderList::CanAllocateItem()) { v->orders.list = new OrderList(this->orders, v); this->orders = nullptr; @@ -88,7 +88,7 @@ void OrderBackup::DoRestore(Vehicle *v) if (v->cur_implicit_order_index >= v->GetNumOrders()) v->cur_implicit_order_index = v->cur_real_order_index; /* Restore vehicle group */ - DoCommand(0, this->group, v->index, DC_EXEC, CMD_ADD_VEHICLE_GROUP); + DoCommand(DC_EXEC, CMD_ADD_VEHICLE_GROUP, 0, this->group, v->index); } /** diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index f282ca12bd..b681b63796 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -2036,7 +2036,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool v->current_order.MakeGoToDepot(destination, v->current_order.GetDepotOrderType(), v->current_order.GetNonStopType(), (OrderDepotActionFlags)(v->current_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT), v->current_order.GetRefitCargo()); /* If there is no depot in front, reverse automatically (trains only) */ - if (v->type == VEH_TRAIN && reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); + if (v->type == VEH_TRAIN && reverse) DoCommand(DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION, v->tile, v->index, 0); if (v->type == VEH_AIRCRAFT) { Aircraft *a = Aircraft::From(v); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 4c34f1ca86..8ff8d64539 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -451,7 +451,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u CommandCost ret = CheckTileOwnership(tile); if (ret.Failed()) return ret; - if (!IsPlainRail(tile)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); // just get appropriate error message + if (!IsPlainRail(tile)) return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); // just get appropriate error message if (!IsCompatibleRail(GetRailType(tile), railtype)) return_cmd_error(STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION); @@ -469,7 +469,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u for (Track track_it = TRACK_BEGIN; track_it < TRACK_END; track_it++) { if (HasTrack(tile, track_it) && HasSignalOnTrack(tile, track_it)) { - CommandCost ret_remove_signals = DoCommand(tile, track_it, 0, flags, CMD_REMOVE_SIGNALS); + CommandCost ret_remove_signals = DoCommand(flags, CMD_REMOVE_SIGNALS, tile, track_it, 0); if (ret_remove_signals.Failed()) return ret_remove_signals; cost.AddCost(ret_remove_signals); } @@ -481,7 +481,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u * the present rail type are powered on the new rail type. */ if (GetRailType(tile) != railtype && !HasPowerOnRail(railtype, GetRailType(tile))) { if (HasPowerOnRail(GetRailType(tile), railtype)) { - ret = DoCommand(tile, tile, railtype, flags, CMD_CONVERT_RAIL); + ret = DoCommand(flags, CMD_CONVERT_RAIL, tile, tile, railtype); if (ret.Failed()) return ret; cost.AddCost(ret); } else { @@ -581,7 +581,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (ret.Failed()) return ret; cost.AddCost(ret); - ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -691,7 +691,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, /* Charge extra to remove signals on the track, if they are there */ if (HasSignalOnTrack(tile, track)) { - cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS)); + cost.AddCost(DoCommand(flags, CMD_REMOVE_SIGNALS, tile, track, 0)); } if (flags & DC_EXEC) { @@ -784,7 +784,7 @@ bool FloodHalftile(TileIndex t) TrackBits to_remove = lower_track & rail_bits; if (to_remove != 0) { Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); - flooded = DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL).Succeeded(); + flooded = DoCommand(DC_EXEC, CMD_REMOVE_SINGLE_RAIL, t, 0, FIND_FIRST_BIT(to_remove)).Succeeded(); cur_company.Restore(); if (!flooded) return flooded; // not yet floodable rail_bits = rail_bits & ~to_remove; @@ -903,7 +903,7 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint3 bool had_success = false; CommandCost last_error = CMD_ERROR; for (;;) { - CommandCost ret = DoCommand(tile, remove ? 0 : railtype, TrackdirToTrack(trackdir) | (auto_remove_signals << 3), flags, remove ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL); + CommandCost ret = DoCommand(flags, remove ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL, tile, remove ? 0 : railtype, TrackdirToTrack(trackdir) | (auto_remove_signals << 3)); if (ret.Failed()) { last_error = ret; @@ -1007,7 +1007,7 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u cost.AddCost(_price[PR_BUILD_FOUNDATION]); } - cost.AddCost(DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)); + cost.AddCost(DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0)); if (cost.Failed()) return cost; if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -1358,7 +1358,7 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(trackdir); if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(trackdir); - CommandCost ret = DoCommand(tile, param1, signals, test_only ? flags & ~DC_EXEC : flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS); + CommandCost ret = DoCommand(test_only ? flags & ~DC_EXEC : flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS, tile, param1, signals); if (test_only) return ret.Succeeded(); @@ -1878,7 +1878,7 @@ static CommandCost ClearTile_Track(TileIndex tile, DoCommandFlag flags) TrackBits tracks = GetTrackBits(tile); while (tracks != TRACK_BIT_NONE) { Track track = RemoveFirstTrack(&tracks); - CommandCost ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL); + CommandCost ret = DoCommand(flags, CMD_REMOVE_SINGLE_RAIL, tile, 0, track); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -2952,7 +2952,7 @@ static void ChangeTileOwner_Track(TileIndex tile, Owner old_owner, Owner new_own SetTileOwner(tile, new_owner); } else { - DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); + DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } } @@ -3140,7 +3140,7 @@ static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, int AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) { return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index c54e172a0c..9ed9032c45 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -756,7 +756,7 @@ struct BuildRailToolbarWindow : Window { void OnPlacePresize(Point pt, TileIndex tile) override { - DoCommand(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL); + DoCommand(DC_AUTO, CMD_BUILD_TUNNEL, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 70a014434e..942cce7a5e 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -366,7 +366,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec if (!IsTileType(tile, MP_ROAD)) { /* If it's the last roadtype, just clear the whole tile */ - if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); CommandCost cost(EXPENSES_CONSTRUCTION); if (IsTileType(tile, MP_TUNNELBRIDGE)) { @@ -821,7 +821,7 @@ do_clear:; } if (need_to_clear) { - CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -867,7 +867,7 @@ do_clear:; if (HasPowerOnRoad(rt, existing_rt)) { rt = existing_rt; } else if (HasPowerOnRoad(existing_rt, rt)) { - CommandCost ret = DoCommand(tile, tile, rt, flags, CMD_CONVERT_ROAD); + CommandCost ret = DoCommand(flags, CMD_CONVERT_ROAD, tile, tile, rt); if (ret.Failed()) return ret; cost.AddCost(ret); } else { @@ -1038,7 +1038,7 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p if (tile == start_tile && HasBit(p2, 0)) bits &= DiagDirToRoadBits(dir); } - CommandCost ret = DoCommand(tile, drd << 11 | rt << 4 | bits, 0, flags, CMD_BUILD_ROAD); + CommandCost ret = DoCommand(flags, CMD_BUILD_ROAD, tile, drd << 11 | rt << 4 | bits, 0); if (ret.Failed()) { last_error = ret; if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) { @@ -1129,7 +1129,7 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 if (flags & DC_EXEC) { money_spent += ret.GetCost(); if (money_spent > 0 && money_spent > money_available) { - _additional_cash_required = DoCommand(start_tile, end_tile, p2, flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD).GetCost(); + _additional_cash_required = DoCommand(flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD, start_tile, end_tile, p2).GetCost(); return cost; } RemoveRoad(tile, flags, bits, rtt, true, false); @@ -1180,7 +1180,7 @@ CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui cost.AddCost(_price[PR_BUILD_FOUNDATION]); } - cost.AddCost(DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR)); + cost.AddCost(DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0)); if (cost.Failed()) return cost; if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -1266,7 +1266,7 @@ static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags) } if (flags & DC_EXEC) { - DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } return ret; } @@ -2194,7 +2194,7 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne if (IsRoadDepot(tile)) { if (GetTileOwner(tile) == old_owner) { if (new_owner == INVALID_OWNER) { - DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); + DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } else { /* A road depot has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */ RoadType rt = GetRoadTypeRoad(tile); @@ -2231,7 +2231,7 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne if (IsLevelCrossing(tile)) { if (GetTileOwner(tile) == old_owner) { if (new_owner == INVALID_OWNER) { - DoCommand(tile, 0, GetCrossingRailTrack(tile), DC_EXEC | DC_BANKRUPT, CMD_REMOVE_SINGLE_RAIL); + DoCommand(DC_EXEC | DC_BANKRUPT, CMD_REMOVE_SINGLE_RAIL, tile, 0, GetCrossingRailTrack(tile)); } else { /* Update infrastructure counts. No need to dirty windows here, we'll redraw the whole screen anyway. */ Company::Get(old_owner)->infrastructure.rail[GetRailType(tile)] -= LEVELCROSSING_TRACKBIT_FACTOR; @@ -2280,7 +2280,7 @@ static CommandCost TerraformTile_Road(TileIndex tile, DoCommandFlag flags, int z } } - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } /** Update power of road vehicle under which is the roadtype being converted */ diff --git a/src/road_gui.cpp b/src/road_gui.cpp index f6ddbae41f..30d9301aab 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -708,7 +708,7 @@ struct BuildRoadToolbarWindow : Window { void OnPlacePresize(Point pt, TileIndex tile) override { - DoCommand(tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL); + DoCommand(DC_AUTO, CMD_BUILD_TUNNEL, tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); } diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 9c444d1d37..b20748fa05 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1133,7 +1133,7 @@ static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadType rt, RoadB /* The 'current' company is not necessarily the owner of the vehicle. */ Backup cur_company(_current_company, c, FILE_LINE); - CommandCost ret = DoCommand(t, rt << 4 | r, 0, DC_NO_WATER, CMD_BUILD_ROAD); + CommandCost ret = DoCommand(DC_NO_WATER, CMD_BUILD_ROAD, t, rt << 4 | r, 0); cur_company.Restore(); return ret.Succeeded(); diff --git a/src/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp index cd5cc5af72..bbd9df55de 100644 --- a/src/script/api/script_vehicle.cpp +++ b/src/script/api/script_vehicle.cpp @@ -93,7 +93,7 @@ ::VehicleType type = ::Engine::Get(engine_id)->type; - CommandCost res = ::DoCommand(depot, engine_id | (cargo << 24), 0, DC_QUERY_COST, ::GetCmdBuildVeh(type)); + CommandCost res = ::DoCommand(DC_QUERY_COST, ::GetCmdBuildVeh(type), depot, engine_id | (cargo << 24), 0); return res.Succeeded() ? _returned_refit_capacity : -1; } @@ -142,7 +142,7 @@ if (!IsValidVehicle(vehicle_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; - CommandCost res = ::DoCommand(0, vehicle_id, cargo, DC_QUERY_COST, GetCmdRefitVeh(::Vehicle::Get(vehicle_id))); + CommandCost res = ::DoCommand(DC_QUERY_COST, GetCmdRefitVeh(::Vehicle::Get(vehicle_id)), 0, vehicle_id, cargo); return res.Succeeded() ? _returned_refit_capacity : -1; } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 1a188252ce..713d383743 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -841,7 +841,7 @@ static CommandCost CheckFlatLandAirport(AirportTileTableIterator tile_iter, DoCo if (ret.Failed()) return ret; cost.AddCost(ret); - ret = DoCommand(tile_iter, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_iter, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -921,14 +921,14 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl affected_vehicles.push_back(v); } } - CommandCost ret = DoCommand(tile_cur, 0, track, flags, CMD_REMOVE_SINGLE_RAIL); + CommandCost ret = DoCommand(flags, CMD_REMOVE_SINGLE_RAIL, tile_cur, 0, track); if (ret.Failed()) return ret; cost.AddCost(ret); /* With flags & ~DC_EXEC CmdLandscapeClear would fail since the rail still exists */ continue; } } - ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_cur, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -1046,7 +1046,7 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags cost.AddCost(RoadBuildCost(rt) * 2); } } else { - ret = DoCommand(cur_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, cur_tile, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); cost.AddCost(RoadBuildCost(rt) * 2); @@ -1752,7 +1752,7 @@ static CommandCost RemoveRailStation(TileIndex tile, DoCommandFlag flags) { /* if there is flooding, remove platforms tile by tile */ if (_current_company == OWNER_WATER) { - return DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_FROM_RAIL_STATION); + return DoCommand(DC_EXEC, CMD_REMOVE_FROM_RAIL_STATION, tile, 0, 0); } Station *st = Station::GetByTile(tile); @@ -1773,7 +1773,7 @@ static CommandCost RemoveRailWaypoint(TileIndex tile, DoCommandFlag flags) { /* if there is flooding, remove waypoints tile by tile */ if (_current_company == OWNER_WATER) { - return DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_FROM_RAIL_WAYPOINT); + return DoCommand(DC_EXEC, CMD_REMOVE_FROM_RAIL_WAYPOINT, tile, 0, 0); } return RemoveRailStation(Waypoint::GetByTile(tile), flags, _price[PR_CLEAR_WAYPOINT_RAIL]); @@ -2535,7 +2535,7 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_STATION_DOCK]); - ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -2550,7 +2550,7 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Get the water class of the water tile before it is cleared.*/ WaterClass wc = GetWaterClass(tile_cur); - ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_cur, 0, 0); if (ret.Failed()) return ret; tile_cur += TileOffsByDiagDir(direction); @@ -4240,12 +4240,12 @@ static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_o } else { if (IsDriveThroughStopTile(tile)) { /* Remove the drive-through road stop */ - DoCommand(tile, 1 | 1 << 8, (GetStationType(tile) == STATION_TRUCK) ? ROADSTOP_TRUCK : ROADSTOP_BUS, DC_EXEC | DC_BANKRUPT, CMD_REMOVE_ROAD_STOP); + DoCommand(DC_EXEC | DC_BANKRUPT, CMD_REMOVE_ROAD_STOP, tile, 1 | 1 << 8, (GetStationType(tile) == STATION_TRUCK) ? ROADSTOP_TRUCK : ROADSTOP_BUS); assert(IsTileType(tile, MP_ROAD)); /* Change owner of tile and all roadtypes */ ChangeTileOwner(tile, old_owner, new_owner); } else { - DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); + DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); /* Set tile owner of water under (now removed) buoy and dock to OWNER_NONE. * Update owner of buoy if it was not removed (was in orders). * Do not update when owned by OWNER_WATER (sea and rivers). */ @@ -4362,7 +4362,7 @@ static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, in } } } - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } /** diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index eaed9e71c1..205a364165 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -289,7 +289,7 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin } CommandCost cost; if (indirectly_cleared) { - cost = DoCommand(t, 0, 0, tile_flags, CMD_LANDSCAPE_CLEAR); + cost = DoCommand(tile_flags, CMD_LANDSCAPE_CLEAR, t, 0, 0); } else { cost = _tile_type_procs[GetTileType(t)]->terraform_tile_proc(t, tile_flags, z_min, tileh); } @@ -378,7 +378,7 @@ CommandCost CmdLevelLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 TileIndex t = *iter; uint curh = TileHeight(t); while (curh != h) { - CommandCost ret = DoCommand(t, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND); + CommandCost ret = DoCommand(flags & ~DC_EXEC, CMD_TERRAFORM_LAND, t, SLOPE_N, (curh > h) ? 0 : 1); if (ret.Failed()) { last_error = ret; @@ -394,7 +394,7 @@ CommandCost CmdLevelLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 delete iter; return cost; } - DoCommand(t, SLOPE_N, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND); + DoCommand(flags, CMD_TERRAFORM_LAND, t, SLOPE_N, (curh > h) ? 0 : 1); } else { /* When we're at the terraform limit we better bail (unneeded) testing as well. * This will probably cause the terraforming cost to be underestimated, but only diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index f710cecc5c..820287e9ce 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -511,7 +511,7 @@ static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed) /* Delete all station signs */ for (BaseStation *st : BaseStation::Iterate()) { /* There can be buoys, remove them */ - if (IsBuoyTile(st->xy)) DoCommand(st->xy, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); + if (IsBuoyTile(st->xy)) DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, st->xy, 0, 0); if (!st->IsInUse()) delete st; } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 2863b4d6f7..27a9e69783 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -938,8 +938,8 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) * If that fails clear the land, and if that fails exit. * This is to make sure that we can build a road here later. */ RoadType rt = GetTownRoadType(t); - if (DoCommand(tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X) | (rt << 4), 0, DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD).Failed() && - DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Failed()) { + if (DoCommand(DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD, tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X) | (rt << 4), 0).Failed() && + DoCommand(DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Failed()) { return false; } } @@ -956,8 +956,8 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) CommandCost res = CMD_ERROR; if (!_generating_world && Chance16(1, 10)) { /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */ - res = DoCommand(tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, 0, - DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND); + res = DoCommand(DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND, + tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, 0); } if (res.Failed() && Chance16(1, 3)) { /* We can consider building on the slope, though. */ @@ -973,9 +973,9 @@ static bool TerraformTownTile(TileIndex tile, int edges, int dir) { assert(tile < MapSize()); - CommandCost r = DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND); + CommandCost r = DoCommand(DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND, tile, edges, dir); if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false; - DoCommand(tile, edges, dir, DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND); + DoCommand(DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND, tile, edges, dir); return true; } @@ -1107,7 +1107,7 @@ static bool GrowTownWithExtraHouse(Town *t, TileIndex tile) static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd) { RoadType rt = GetTownRoadType(t); - if (DoCommand(tile, rcmd | (rt << 4), t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD).Succeeded()) { + if (DoCommand(DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD, tile, rcmd | (rt << 4), t->index).Succeeded()) { _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1154,7 +1154,7 @@ static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, con if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false; /* If a road tile can be built, the construction is allowed. */ - return DoCommand(next_tile, rcmd | (rt << 4), t->index, DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD).Succeeded(); + return DoCommand(DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD, next_tile, rcmd | (rt << 4), t->index).Succeeded(); } /** @@ -1222,8 +1222,8 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi /* Can we actually build the bridge? */ RoadType rt = GetTownRoadType(t); - if (DoCommand(tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE).Succeeded()) { - DoCommand(tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE); + if (DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE, tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15).Succeeded()) { + DoCommand(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE, tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15); _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1293,8 +1293,8 @@ static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDi /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */ RoadType rt = GetTownRoadType(t); - if (DoCommand(tile, rt | (TRANSPORT_ROAD << 8), 0, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL).Succeeded()) { - DoCommand(tile, rt | (TRANSPORT_ROAD << 8), 0, DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL); + if (DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL, tile, rt | (TRANSPORT_ROAD << 8), 0).Succeeded()) { + DoCommand(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL, tile, rt | (TRANSPORT_ROAD << 8), 0); _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1732,9 +1732,9 @@ static bool GrowTown(Town *t) for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { /* Only work with plain land that not already has a house */ if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) { - if (DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Succeeded()) { + if (DoCommand(DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Succeeded()) { RoadType rt = GetTownRoadType(t); - DoCommand(tile, GenRandomRoadBits() | (rt << 4), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); + DoCommand(DC_EXEC | DC_AUTO, CMD_BUILD_ROAD, tile, GenRandomRoadBits() | (rt << 4), t->index); cur_company.Restore(); return true; } @@ -2179,7 +2179,7 @@ static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size if (t->cache.population > 0) return t; Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); - [[maybe_unused]] CommandCost rc = DoCommand(t->xy, t->index, 0, DC_EXEC, CMD_DELETE_TOWN); + [[maybe_unused]] CommandCost rc = DoCommand(DC_EXEC, CMD_DELETE_TOWN, t->xy, t->index, 0); cur_company.Restore(); assert(rc.Succeeded()); @@ -2280,7 +2280,7 @@ HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile) */ static inline void ClearMakeHouseTile(TileIndex tile, Town *t, byte counter, byte stage, HouseID type, byte random_bits) { - [[maybe_unused]] CommandCost cc = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR); + [[maybe_unused]] CommandCost cc = DoCommand(DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0); assert(cc.Succeeded()); IncreaseBuildingCount(t, type); @@ -2337,7 +2337,7 @@ static inline bool CanBuildHouseHere(TileIndex tile, bool noslope) if (IsBridgeAbove(tile)) return false; /* can we clear the land? */ - return DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Succeeded(); + return DoCommand(DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Succeeded(); } @@ -2972,7 +2972,7 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Non-oil rig stations are always a problem. */ if (!(st->facilities & FACIL_AIRPORT) || st->airport.type != AT_OILRIG) return CMD_ERROR; /* We can only automatically delete oil rigs *if* there's no vehicle on them. */ - CommandCost ret = DoCommand(st->airport.tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, st->airport.tile, 0, 0); if (ret.Failed()) return ret; } } @@ -2988,7 +2988,7 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 * tile was already deleted earlier in the loop. */ for (TileIndex current_tile = 0; current_tile < MapSize(); ++current_tile) { if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) { - CommandCost ret = DoCommand(current_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0); if (ret.Failed()) return ret; } } @@ -3031,7 +3031,7 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 break; } if (try_clear) { - CommandCost ret = DoCommand(current_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0); if (ret.Failed()) return ret; } } @@ -3107,7 +3107,7 @@ static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags) static bool TryClearTile(TileIndex tile) { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); - CommandCost r = DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); + CommandCost r = DoCommand(DC_NONE, CMD_LANDSCAPE_CLEAR, tile, 0, 0); cur_company.Restore(); return r.Succeeded(); } @@ -3179,7 +3179,7 @@ static CommandCost TownActionBuildStatue(Town *t, DoCommandFlag flags) if (flags & DC_EXEC) { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); - DoCommand(statue_data.best_position, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); + DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, statue_data.best_position, 0, 0); cur_company.Restore(); BuildObject(OBJECT_STATUE, statue_data.best_position, _current_company, t); SetBit(t->statues, _current_company); // Once found and built, "inform" the Town. @@ -3786,7 +3786,7 @@ static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, int z } } - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } /** Tile callback functions for a town */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index f5eb32d7f9..775b1f6374 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -654,7 +654,7 @@ static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const w->engine_type == e->index && ///< Same type w->First() != v && ///< Don't connect to ourself !(w->vehstatus & VS_CRASHED)) { ///< Not crashed/flooded - if (DoCommand(0, v->index | 1 << 20, w->Last()->index, DC_EXEC, CMD_MOVE_RAIL_VEHICLE).Succeeded()) { + if (DoCommand(DC_EXEC, CMD_MOVE_RAIL_VEHICLE, 0, v->index | 1 << 20, w->Last()->index).Succeeded()) { break; } } @@ -670,9 +670,9 @@ static void NormalizeTrainVehInDepot(const Train *u) for (const Train *v : Train::Iterate()) { if (v->IsFreeWagon() && v->tile == u->tile && v->track == TRACK_BIT_DEPOT) { - if (DoCommand(0, v->index | 1 << 20, u->index, DC_EXEC, - CMD_MOVE_RAIL_VEHICLE).Failed()) + if (DoCommand(DC_EXEC, CMD_MOVE_RAIL_VEHICLE, 0, v->index | 1 << 20, u->index).Failed()) { break; + } } } } diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index 237b34fffb..626f0386f7 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -460,7 +460,7 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 switch (GetRawClearGround(current_tile)) { case CLEAR_FIELDS: case CLEAR_ROCKS: { - CommandCost ret = DoCommand(current_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); break; @@ -881,7 +881,7 @@ void InitializeTrees() static CommandCost TerraformTile_Trees(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 5181dfdca2..9c77dff9dc 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -418,7 +418,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u bool allow_on_slopes = (_settings_game.construction.build_on_slopes && transport_type != TRANSPORT_WATER); /* Try and clear the start landscape */ - CommandCost ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_start, 0, 0); if (ret.Failed()) return ret; cost = ret; @@ -426,7 +426,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u cost.AddCost(terraform_cost_north); /* Try and clear the end landscape */ - ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_end, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -498,7 +498,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u default: not_valid_below:; /* try and clear the middle landscape */ - ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); break; @@ -672,7 +672,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, if (HasTileWaterGround(start_tile)) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER); - CommandCost ret = DoCommand(start_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, start_tile, 0, 0); if (ret.Failed()) return ret; /* XXX - do NOT change 'ret' in the loop, as it is used as the price @@ -732,7 +732,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, if (HasTileWaterGround(end_tile)) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER); /* Clear the tile in any case */ - ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, end_tile, 0, 0); if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND); cost.AddCost(ret); @@ -764,7 +764,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, assert(coa_index < UINT_MAX); // more than 2**32 cleared areas would be a bug in itself coa = nullptr; - ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND); + ret = DoCommand(flags, CMD_TERRAFORM_LAND, end_tile, end_tileh & start_tileh, 0); _cleared_object_areas[(uint)coa_index].first_tile = old_first_tile; if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND); cost.AddCost(ret); @@ -1846,7 +1846,7 @@ static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner if (tt == TRANSPORT_RAIL) { /* Since all of our vehicles have been removed, it is safe to remove the rail * bridge / tunnel. */ - [[maybe_unused]] CommandCost ret = DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); + [[maybe_unused]] CommandCost ret = DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); assert(ret.Succeeded()); } else { /* In any other case, we can safely reassign the ownership to OWNER_NONE. */ @@ -2037,7 +2037,7 @@ static CommandCost TerraformTile_TunnelBridge(TileIndex tile, DoCommandFlag flag if (res.Succeeded() && (z_old == z_new) && (tileh_old == tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } extern const TileTypeProcs _tile_type_tunnelbridge_procs = { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 30e1c477cb..1e0cccaadc 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -307,7 +307,7 @@ void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRF SetDParamStr(0, grfconfig->GetName()); SetDParam(1, engine); ShowErrorMessage(part1, part2, WL_CRITICAL); - if (!_networking) DoCommand(0, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, 1, DC_EXEC, CMD_PAUSE); + if (!_networking) DoCommand(DC_EXEC, CMD_PAUSE, 0, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, 1); } /* debug output */ @@ -1055,7 +1055,7 @@ void CallVehicleTicks() const Company *c = Company::Get(_current_company); SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money)); - CommandCost res = DoCommand(0, v->index, 0, DC_EXEC, CMD_AUTOREPLACE_VEHICLE); + CommandCost res = DoCommand(DC_EXEC, CMD_AUTOREPLACE_VEHICLE, 0, v->index, 0); SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money)); if (!IsLocalCompany()) continue; @@ -1561,7 +1561,7 @@ void VehicleEnterDepot(Vehicle *v) if (v->current_order.IsRefit()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - CommandCost cost = DoCommand(v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8, DC_EXEC, GetCmdRefitVeh(v)); + CommandCost cost = DoCommand(DC_EXEC, GetCmdRefitVeh(v), v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8); cur_company.Restore(); if (cost.Failed()) { @@ -2443,7 +2443,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) /* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */ if (this->type == VEH_TRAIN && (reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) { - DoCommand(this->tile, this->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); + DoCommand(DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION, this->tile, this->index, 0); } if (this->type == VEH_AIRCRAFT) { diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index f3e0a99b8b..5b1878c3a8 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -182,7 +182,7 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /* If we are not in DC_EXEC undo everything */ if (flags != subflags) { - DoCommand(0, v->index, 0, DC_EXEC, GetCmdSellVeh(v)); + DoCommand(DC_EXEC, GetCmdSellVeh(v), 0, v->index, 0); } } @@ -665,7 +665,7 @@ CommandCost CmdMassStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 if (!vehicle_list_window && !v->IsChainInDepot()) continue; /* Just try and don't care if some vehicle's can't be stopped. */ - DoCommand(tile, v->index, 0, flags, CMD_START_STOP_VEHICLE); + DoCommand(flags, CMD_START_STOP_VEHICLE, tile, v->index, 0); } return CommandCost(); @@ -697,7 +697,7 @@ CommandCost CmdDepotSellAllVehicles(TileIndex tile, DoCommandFlag flags, uint32 CommandCost last_error = CMD_ERROR; bool had_success = false; for (uint i = 0; i < list.size(); i++) { - CommandCost ret = DoCommand(tile, list[i]->index | (1 << 20), 0, flags, sell_command); + CommandCost ret = DoCommand(flags, sell_command, tile, list[i]->index | (1 << 20), 0); if (ret.Succeeded()) { cost.AddCost(ret); had_success = true; @@ -736,7 +736,7 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 /* Ensure that the vehicle completely in the depot */ if (!v->IsChainInDepot()) continue; - CommandCost ret = DoCommand(0, v->index, 0, flags, CMD_AUTOREPLACE_VEHICLE); + CommandCost ret = DoCommand(flags, CMD_AUTOREPLACE_VEHICLE, 0, v->index, 0); if (ret.Succeeded()) cost.AddCost(ret); } @@ -875,11 +875,11 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint DoCommandFlag build_flags = flags; if ((flags & DC_EXEC) && !v->IsPrimaryVehicle()) build_flags |= DC_AUTOREPLACE; - CommandCost cost = DoCommand(tile, v->engine_type | (1 << 16) | (CT_INVALID << 24), 0, build_flags, GetCmdBuildVeh(v)); + CommandCost cost = DoCommand(build_flags, GetCmdBuildVeh(v), tile, v->engine_type | (1 << 16) | (CT_INVALID << 24), 0); if (cost.Failed()) { /* Can't build a part, then sell the stuff we already made; clear up the mess */ - if (w_front != nullptr) DoCommand(w_front->tile, w_front->index | (1 << 20), 0, flags, GetCmdSellVeh(w_front)); + if (w_front != nullptr) DoCommand(flags, GetCmdSellVeh(w_front), w_front->tile, w_front->index | (1 << 20), 0); return cost; } @@ -895,12 +895,12 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint if (v->type == VEH_TRAIN && !v->IsFrontEngine()) { /* this s a train car * add this unit to the end of the train */ - CommandCost result = DoCommand(0, w->index | 1 << 20, w_rear->index, flags, CMD_MOVE_RAIL_VEHICLE); + CommandCost result = DoCommand(flags, CMD_MOVE_RAIL_VEHICLE, 0, w->index | 1 << 20, w_rear->index); if (result.Failed()) { /* The train can't be joined to make the same consist as the original. * Sell what we already made (clean up) and return an error. */ - DoCommand(w_front->tile, w_front->index | 1 << 20, 0, flags, GetCmdSellVeh(w_front)); - DoCommand(w_front->tile, w->index | 1 << 20, 0, flags, GetCmdSellVeh(w)); + DoCommand(flags, GetCmdSellVeh(w_front), w_front->tile, w_front->index | 1 << 20, 0); + DoCommand(flags, GetCmdSellVeh(w) , w_front->tile, w->index | 1 << 20, 0); return result; // return error and the message returned from CMD_MOVE_RAIL_VEHICLE } } else { @@ -921,7 +921,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint if (flags & DC_EXEC) { /* Cloned vehicles belong to the same group */ - DoCommand(0, v_front->group_id, w_front->index, flags, CMD_ADD_VEHICLE_GROUP); + DoCommand(flags, CMD_ADD_VEHICLE_GROUP, 0, v_front->group_id, w_front->index); } @@ -943,7 +943,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /* Find out what's the best sub type */ byte subtype = GetBestFittingSubType(v, w, v->cargo_type); if (w->cargo_type != v->cargo_type || w->cargo_subtype != subtype) { - CommandCost cost = DoCommand(0, w->index, v->cargo_type | 1U << 25 | (subtype << 8), flags, GetCmdRefitVeh(v)); + CommandCost cost = DoCommand(flags, GetCmdRefitVeh(v), 0, w->index, v->cargo_type | 1U << 25 | (subtype << 8)); if (cost.Succeeded()) total_cost.AddCost(cost); } @@ -978,10 +978,10 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint * the vehicle refitted before doing this, otherwise the moved * cargo types might not match (passenger vs non-passenger) */ - CommandCost result = DoCommand(0, w_front->index | (p2 & 1 ? CO_SHARE : CO_COPY) << 30, v_front->index, flags, CMD_CLONE_ORDER); + CommandCost result = DoCommand(flags, CMD_CLONE_ORDER, 0, w_front->index | (p2 & 1 ? CO_SHARE : CO_COPY) << 30, v_front->index); if (result.Failed()) { /* The vehicle has already been bought, so now it must be sold again. */ - DoCommand(w_front->tile, w_front->index | 1 << 20, 0, flags, GetCmdSellVeh(w_front)); + DoCommand(flags, GetCmdSellVeh(w_front), w_front->tile, w_front->index | 1 << 20, 0); return result; } @@ -992,7 +992,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint * check whether the company has enough money manually. */ if (!CheckCompanyHasMoney(total_cost)) { /* The vehicle has already been bought, so now it must be sold again. */ - DoCommand(w_front->tile, w_front->index | 1 << 20, 0, flags, GetCmdSellVeh(w_front)); + DoCommand(flags, GetCmdSellVeh(w_front), w_front->tile, w_front->index | 1 << 20, 0); return total_cost; } } @@ -1017,7 +1017,7 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con bool had_success = false; for (uint i = 0; i < list.size(); i++) { const Vehicle *v = list[i]; - CommandCost ret = DoCommand(v->tile, v->index | (service ? DEPOT_SERVICE : 0U) | DEPOT_DONT_CANCEL, 0, flags, GetCmdSendToDepot(vli.vtype)); + CommandCost ret = DoCommand(flags, GetCmdSendToDepot(vli.vtype), v->tile, v->index | (service ? DEPOT_SERVICE : 0U) | DEPOT_DONT_CANCEL, 0); if (ret.Succeeded()) { had_success = true; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index f2ab811574..e11e340f59 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -772,8 +772,8 @@ struct RefitWindow : public Window { { assert(_current_company == _local_company); Vehicle *v = Vehicle::Get(this->window_number); - CommandCost cost = DoCommand(v->tile, this->selected_vehicle, option->cargo | option->subtype << 8 | this->num_vehicles << 16 | - (int)this->auto_refit << 24, DC_QUERY_COST, GetCmdRefitVeh(v->type)); + CommandCost cost = DoCommand(DC_QUERY_COST, GetCmdRefitVeh(v->type), v->tile, this->selected_vehicle, option->cargo | + option->subtype << 8 | this->num_vehicles << 16 | (int)this->auto_refit << 24); if (cost.Failed()) return INVALID_STRING_ID; diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index ba09b415a7..12f300ac2c 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -122,13 +122,13 @@ CommandCost CmdBuildShipDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_DEPOT_SHIP]); bool add_cost = !IsWaterTile(tile); - CommandCost ret = DoCommand(tile, 0, 0, flags | DC_AUTO, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags | DC_AUTO, CMD_LANDSCAPE_CLEAR, tile, 0, 0); if (ret.Failed()) return ret; if (add_cost) { cost.AddCost(ret); } add_cost = !IsWaterTile(tile2); - ret = DoCommand(tile2, 0, 0, flags | DC_AUTO, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags | DC_AUTO, CMD_LANDSCAPE_CLEAR, tile2, 0, 0); if (ret.Failed()) return ret; if (add_cost) { cost.AddCost(ret); @@ -306,13 +306,13 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag /* middle tile */ WaterClass wc_middle = HasTileWaterGround(tile) ? GetWaterClass(tile) : WATER_CLASS_CANAL; - ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); /* lower tile */ if (!IsWaterTile(tile - delta)) { - ret = DoCommand(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile - delta, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); cost.AddCost(_price[PR_BUILD_CANAL]); @@ -324,7 +324,7 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag /* upper tile */ if (!IsWaterTile(tile + delta)) { - ret = DoCommand(tile + delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile + delta, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); cost.AddCost(_price[PR_BUILD_CANAL]); @@ -480,7 +480,7 @@ CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Outside the editor, prevent building canals over your own or OWNER_NONE owned canals */ if (water && IsCanal(current_tile) && _game_mode != GM_EDITOR && (IsTileOwner(current_tile, _current_company) || IsTileOwner(current_tile, OWNER_NONE))) continue; - ret = DoCommand(current_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0); if (ret.Failed()) return ret; if (!water) cost.AddCost(ret); @@ -1135,7 +1135,7 @@ void DoFloodTile(TileIndex target) FALLTHROUGH; case MP_CLEAR: - if (DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR).Succeeded()) { + if (DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, target, 0, 0).Succeeded()) { MakeShore(target); MarkTileDirtyByTile(target); flooded = true; @@ -1150,7 +1150,7 @@ void DoFloodTile(TileIndex target) FloodVehicles(target); /* flood flat tile */ - if (DoCommand(target, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR).Succeeded()) { + if (DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, target, 0, 0).Succeeded()) { MakeSea(target); MarkTileDirtyByTile(target); flooded = true; @@ -1202,7 +1202,7 @@ static void DoDryUp(TileIndex tile) case MP_WATER: assert(IsCoast(tile)); - if (DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR).Succeeded()) { + if (DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Succeeded()) { MakeClear(tile, CLEAR_GRASS, 3); MarkTileDirtyByTile(tile); } @@ -1361,7 +1361,7 @@ static void ChangeTileOwner_Water(TileIndex tile, Owner old_owner, Owner new_own } /* Remove depot */ - if (IsShipDepot(tile)) DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); + if (IsShipDepot(tile)) DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); /* Set owner of canals and locks ... and also canal under dock there was before. * Check if the new owner after removing depot isn't OWNER_WATER. */ @@ -1381,7 +1381,7 @@ static CommandCost TerraformTile_Water(TileIndex tile, DoCommandFlag flags, int /* Canals can't be terraformed */ if (IsWaterTile(tile) && IsCanal(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST); - return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); } diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 632d697429..77b9fbd027 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -315,7 +315,7 @@ CommandCost CmdBuildBuoy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_WAYPOINT_BUOY]); if (!IsWaterTile(tile)) { - CommandCost ret = DoCommand(tile, 0, 0, flags | DC_AUTO, CMD_LANDSCAPE_CLEAR); + CommandCost ret = DoCommand(flags | DC_AUTO, CMD_LANDSCAPE_CLEAR, tile, 0, 0); if (ret.Failed()) return ret; cost.AddCost(ret); } From 549caca39cebc8c988f4e51d79d353cab4646d58 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 3 Oct 2021 17:15:48 +0200 Subject: [PATCH 04/60] Codechange: Move command arguments to the back of the networked command function calls. --- src/ai/ai_gui.cpp | 8 ++-- src/autoreplace_gui.cpp | 10 ++-- src/bridge_gui.cpp | 6 +-- src/build_vehicle_gui.cpp | 6 +-- src/cheat_gui.cpp | 2 +- src/command.cpp | 74 +++++++++++++++++++++-------- src/command_func.h | 7 +-- src/company_cmd.cpp | 2 +- src/company_gui.cpp | 24 +++++----- src/console_cmds.cpp | 14 +++--- src/depot_gui.cpp | 20 ++++---- src/dock_gui.cpp | 12 ++--- src/economy.cpp | 2 +- src/engine_gui.cpp | 2 +- src/fios_gui.cpp | 4 +- src/goal_gui.cpp | 6 +-- src/group_gui.cpp | 24 +++++----- src/highscore_gui.cpp | 8 ++-- src/industry_gui.cpp | 7 ++- src/linkgraph/linkgraphschedule.cpp | 4 +- src/main_gui.cpp | 2 +- src/misc_cmd.cpp | 2 +- src/network/network.cpp | 4 +- src/network/network_client.cpp | 2 +- src/network/network_command.cpp | 8 ++-- src/network/network_gui.cpp | 6 +-- src/network/network_server.cpp | 6 +-- src/object_gui.cpp | 4 +- src/openttd.cpp | 8 ++-- src/order_backup.cpp | 4 +- src/order_gui.cpp | 46 +++++++++--------- src/rail_gui.cpp | 42 ++++++++-------- src/road_gui.cpp | 22 ++++----- src/script/api/script_object.cpp | 2 +- src/settings.cpp | 6 +-- src/signs_cmd.cpp | 2 +- src/signs_gui.cpp | 2 +- src/station_gui.cpp | 4 +- src/story_gui.cpp | 6 +-- src/terraform_gui.cpp | 16 +++---- src/timetable_gui.cpp | 12 ++--- src/toolbar_gui.cpp | 2 +- src/town_gui.cpp | 12 ++--- src/train_cmd.cpp | 2 +- src/train_gui.cpp | 2 +- src/tree_gui.cpp | 4 +- src/vehicle_gui.cpp | 29 ++++++----- src/waypoint_gui.cpp | 2 +- 48 files changed, 265 insertions(+), 236 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index c7ae4740e2..340b6db956 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -1290,8 +1290,8 @@ struct AIDebugWindow : public Window { case WID_AID_RELOAD_TOGGLE: if (ai_debug_company == OWNER_DEITY) break; /* First kill the company of the AI, then start a new one. This should start the current AI again */ - DoCommandP(0, CCA_DELETE | ai_debug_company << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL); - DoCommandP(0, CCA_NEW_AI | ai_debug_company << 16, 0, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | ai_debug_company << 16 | CRR_MANUAL << 24, 0); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | ai_debug_company << 16, 0); break; case WID_AID_SETTINGS: @@ -1330,7 +1330,7 @@ struct AIDebugWindow : public Window { } if (all_unpaused) { /* All scripts have been unpaused => unpause the game. */ - DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); } } } @@ -1379,7 +1379,7 @@ struct AIDebugWindow : public Window { /* Pause the game. */ if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); } /* Highlight row that matched */ diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 898b4e7503..d4e392c971 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -217,7 +217,7 @@ class ReplaceVehicleWindow : public Window { { EngineID veh_from = this->sel_engine[0]; EngineID veh_to = this->sel_engine[1]; - DoCommandP(0, (replace_when_old ? 1 : 0) | (this->sel_group << 16), veh_from + (veh_to << 16), CMD_SET_AUTOREPLACE); + DoCommandP(CMD_SET_AUTOREPLACE, 0, (replace_when_old ? 1 : 0) | (this->sel_group << 16), veh_from + (veh_to << 16)); } public: @@ -541,10 +541,10 @@ public: case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: { const Group *g = Group::GetIfValid(this->sel_group); if (g != nullptr) { - DoCommandP(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG); + DoCommandP(CMD_SET_GROUP_FLAG, 0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1)); } else { // toggle renew_keep_length - DoCommandP(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING, nullptr, "company.renew_keep_length"); + DoCommandP(CMD_CHANGE_COMPANY_SETTING, 0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, "company.renew_keep_length"); } break; } @@ -562,7 +562,7 @@ public: case WID_RV_STOP_REPLACE: { // Stop replacing EngineID veh_from = this->sel_engine[0]; - DoCommandP(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), CMD_SET_AUTOREPLACE); + DoCommandP(CMD_SET_AUTOREPLACE, 0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16)); break; } @@ -584,7 +584,7 @@ public: if (click_side == 0 && _ctrl_pressed && e != INVALID_ENGINE && (GetGroupNumEngines(_local_company, sel_group, e) == 0 || GetGroupNumEngines(_local_company, ALL_GROUP, e) == 0)) { EngineID veh_from = e; - DoCommandP(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), CMD_SET_AUTOREPLACE); + DoCommandP(CMD_SET_AUTOREPLACE, 0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16)); break; } diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 9e6fc4eeef..2aef088e3f 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -117,8 +117,8 @@ private: case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->at(i).index; break; default: break; } - DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->at(i).index, - CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge); + DoCommandP(CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge, + this->end_tile, this->start_tile, this->type | this->bridges->at(i).index); } /** Sort the builable bridges */ @@ -383,7 +383,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo default: break; // water ways and air routes don't have bridge types } if (_ctrl_pressed && CheckBridgeAvailability(last_bridge_type, bridge_len).Succeeded()) { - DoCommandP(end, start, type | last_bridge_type, CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge); + DoCommandP(CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge, end, start, type | last_bridge_type); return; } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 6bee767b0c..aafc0a950e 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1458,7 +1458,7 @@ struct BuildVehicleWindow : Window { case WID_BV_SHOW_HIDE: { const Engine *e = (this->sel_engine == INVALID_ENGINE) ? nullptr : Engine::Get(this->sel_engine); if (e != nullptr) { - DoCommandP(0, 0, this->sel_engine | (e->IsHidden(_current_company) ? 0 : (1u << 31)), CMD_SET_VEHICLE_VISIBILITY); + DoCommandP(CMD_SET_VEHICLE_VISIBILITY, 0, 0, this->sel_engine | (e->IsHidden(_current_company) ? 0 : (1u << 31))); } break; } @@ -1469,7 +1469,7 @@ struct BuildVehicleWindow : Window { CommandCallback *callback = (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildPrimaryVehicle; CargoID cargo = this->cargo_filter[this->cargo_filter_criteria]; if (cargo == CF_ANY || cargo == CF_ENGINES) cargo = CF_NONE; - DoCommandP(this->window_number, sel_eng | (cargo << 24), 0, GetCmdBuildVeh(this->vehicle_type), callback); + DoCommandP(GetCmdBuildVeh(this->vehicle_type), callback, this->window_number, sel_eng | (cargo << 24), 0); } break; } @@ -1634,7 +1634,7 @@ struct BuildVehicleWindow : Window { { if (str == nullptr) return; - DoCommandP(0, this->rename_engine, 0, CMD_RENAME_ENGINE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type), nullptr, str); + DoCommandP(CMD_RENAME_ENGINE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type), 0, this->rename_engine, 0, str); } void OnDropdownSelect(int widget, int index) override diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index a0ac5fab8f..84884b3ded 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -54,7 +54,7 @@ static int32 _money_cheat_amount = 10000000; */ static int32 ClickMoneyCheat(int32 p1, int32 p2) { - DoCommandP(0, (uint32)(p2 * _money_cheat_amount), 0, CMD_MONEY_CHEAT); + DoCommandP(CMD_MONEY_CHEAT, 0, (uint32)(p2 * _money_cheat_amount), 0); return _money_cheat_amount; } diff --git a/src/command.cpp b/src/command.cpp index b971ccb6bd..d397d3fe6a 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -532,16 +532,6 @@ Money GetAvailableMoneyForCommand() return Company::Get(company)->money; } -/** - * Shortcut for the long DoCommandP when having a container with the data. - * @param container the container with information. - * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) - * @return true if the command succeeded, else false - */ -bool DoCommandP(const CommandContainer *container, bool my_cmd) -{ - return DoCommandP(container->tile, container->p1, container->p2, container->cmd, container->callback, container->text, my_cmd); -} /*! * Toplevel network safe docommand function for the current company. Must not be called recursively. @@ -549,16 +539,16 @@ bool DoCommandP(const CommandContainer *container, bool my_cmd) * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. * The parameter \a my_cmd is used to indicate if the command is from a company or the server. * + * @param cmd The command to execute (a CMD_* value) + * @param callback A callback function to call after the command is finished + * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) * @param tile The tile to perform a command on (see #CommandProc) * @param p1 Additional data for the command (see #CommandProc) * @param p2 Additional data for the command (see #CommandProc) - * @param cmd The command to execute (a CMD_* value) - * @param callback A callback function to call after the command is finished * @param text The text to pass - * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) * @return \c true if the command succeeded, else \c false. */ -bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, bool my_cmd) +static bool DoCommandP(uint32 cmd, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* Cost estimation is generally only done when the * local user presses shift while doing something. @@ -586,7 +576,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac /* Only set p2 when the command does not come from the network. */ if (!(cmd & CMD_NETWORK_COMMAND) && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER; - CommandCost res = DoCommandPInternal(tile, p1, p2, cmd, callback, text, my_cmd, estimate_only); + CommandCost res = DoCommandPInternal(cmd, callback, my_cmd, estimate_only, tile, p1, p2, text); if (res.Failed()) { /* Only show the error when it's for us. */ StringID error_part1 = GB(cmd, 16, 16); @@ -611,6 +601,48 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac return res.Succeeded(); } +/** + * Shortcut for the long DoCommandP when having a container with the data. + * @param container the container with information. + * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) + * @return true if the command succeeded, else false + */ +bool DoCommandP(const CommandContainer *container, bool my_cmd) +{ + return DoCommandP(container->cmd, container->callback, my_cmd, container->tile, container->p1, container->p2, container->text); +} + +/** + * Shortcut for the long DoCommandP when not using a callback. + * @param cmd The command to execute (a CMD_* value) + * @param tile The tile to perform a command on (see #CommandProc) + * @param p1 Additional data for the command (see #CommandProc) + * @param p2 Additional data for the command (see #CommandProc) + * @param text The text to pass + * @return \c true if the command succeeded, else \c false. + */ +bool DoCommandP(uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +{ + return DoCommandP(cmd, nullptr, true, tile, p1, p2, text); +} + +/*! + * Toplevel network safe docommand function for the current company. Must not be called recursively. + * The callback is called when the command succeeded or failed. The parameters + * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. + * + * @param cmd The command to execute (a CMD_* value) + * @param callback A callback function to call after the command is finished + * @param tile The tile to perform a command on (see #CommandProc) + * @param p1 Additional data for the command (see #CommandProc) + * @param p2 Additional data for the command (see #CommandProc) + * @param text The text to pass + * @return \c true if the command succeeded, else \c false. + */ +bool DoCommandP(uint32 cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +{ + return DoCommandP(cmd, callback, true, tile, p1, p2, text); +} /** * Helper to deduplicate the code for returning. @@ -621,17 +653,17 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac /*! * Helper function for the toplevel network safe docommand function for the current company. * - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) * @param cmd The command to execute (a CMD_* value) * @param callback A callback function to call after the command is finished - * @param text The text to pass * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) * @param estimate_only whether to give only the estimate or also execute the command + * @param tile The tile to perform a command on (see #CommandProc) + * @param p1 Additional data for the command (see #CommandProc) + * @param p2 Additional data for the command (see #CommandProc) + * @param text The text to pass * @return the command cost of this function. */ -CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, bool my_cmd, bool estimate_only) +CommandCost DoCommandPInternal(uint32 cmd, CommandCallback *callback, bool my_cmd, bool estimate_only, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* Prevent recursion; it gives a mess over the network */ assert(_docommand_recursive == 0); @@ -707,7 +739,7 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, * send it to the command-queue and abort execution */ if (_networking && !_generating_world && !(cmd & CMD_NETWORK_COMMAND)) { - NetworkSendCommand(tile, p1, p2, cmd & ~CMD_FLAGS_MASK, callback, text, _current_company); + NetworkSendCommand(cmd & ~CMD_FLAGS_MASK, callback, _current_company, tile, p1, p2, text); cur_company.Restore(); /* Don't return anything special here; no error, no costs. diff --git a/src/command_func.h b/src/command_func.h index 07de8de9c0..eefaadd9b6 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -35,12 +35,13 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); CommandCost DoCommand(DoCommandFlag flags, uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags); -bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr, const std::string &text = {}, bool my_cmd = true); +bool DoCommandP(uint32 cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); +bool DoCommandP(uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); bool DoCommandP(const CommandContainer *container, bool my_cmd = true); -CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, bool my_cmd, bool estimate_only); +CommandCost DoCommandPInternal(uint32 cmd, CommandCallback *callback, bool my_cmd, bool estimate_only, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); -void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, CompanyID company); +void NetworkSendCommand(uint32 cmd, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); extern Money _additional_cash_required; diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index ce7488f037..792dd624b2 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -603,7 +603,7 @@ static bool MaybeStartNewCompany() if (n < (uint)_settings_game.difficulty.max_no_competitors) { /* Send a command to all clients to start up a new AI. * Works fine for Multiplayer and Singleplayer */ - return DoCommandP(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, CMD_COMPANY_CTRL); + return DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | INVALID_COMPANY << 16, 0); } return false; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index fe8c2326c2..d8b468ad91 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -435,11 +435,11 @@ struct CompanyFinancesWindow : Window { break; case WID_CF_INCREASE_LOAN: // increase loan - DoCommandP(0, 0, _ctrl_pressed, CMD_INCREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY)); + DoCommandP(CMD_INCREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY), 0, 0, _ctrl_pressed); break; case WID_CF_REPAY_LOAN: // repay loan - DoCommandP(0, 0, _ctrl_pressed, CMD_DECREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_REPAY_LOAN)); + DoCommandP(CMD_DECREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_REPAY_LOAN), 0, 0, _ctrl_pressed); break; case WID_CF_INFRASTRUCTURE: // show infrastructure details @@ -995,12 +995,12 @@ public: for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) { /* Changed colour for the selected scheme, or all visible schemes if CTRL is pressed. */ if (HasBit(this->sel, scheme) || (_ctrl_pressed && _livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme))) { - DoCommandP(0, scheme | (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256), index, CMD_SET_COMPANY_COLOUR); + DoCommandP(CMD_SET_COMPANY_COLOUR, 0, scheme | (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256), index); } } } else { /* Setting group livery */ - DoCommandP(0, this->sel, (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256) | (index << 16), CMD_SET_GROUP_LIVERY); + DoCommandP(CMD_SET_GROUP_LIVERY, 0, this->sel, (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256) | (index << 16)); } } @@ -1581,7 +1581,7 @@ public: /* OK button */ case WID_SCMF_ACCEPT: - DoCommandP(0, 0, this->face, CMD_SET_COMPANY_MANAGER_FACE); + DoCommandP(CMD_SET_COMPANY_MANAGER_FACE, 0, 0, this->face); FALLTHROUGH; /* Cancel button */ @@ -2576,11 +2576,11 @@ struct CompanyWindow : Window break; case WID_C_BUY_SHARE: - DoCommandP(0, this->window_number, 0, CMD_BUY_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS)); + DoCommandP(CMD_BUY_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS), 0, this->window_number, 0); break; case WID_C_SELL_SHARE: - DoCommandP(0, this->window_number, 0, CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_SELL_25_SHARE_IN)); + DoCommandP(CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_SELL_25_SHARE_IN), 0, this->window_number, 0); break; case WID_C_COMPANY_PASSWORD: @@ -2613,7 +2613,7 @@ struct CompanyWindow : Window void OnPlaceObject(Point pt, TileIndex tile) override { - if (DoCommandP(tile, OBJECT_HQ, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS)) && !_shift_pressed) { + if (DoCommandP(CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS), tile, OBJECT_HQ, 0) && !_shift_pressed) { ResetObjectToPlace(); this->RaiseButtons(); } @@ -2635,16 +2635,16 @@ struct CompanyWindow : Window Money money = (Money)(strtoull(str, nullptr, 10) / _currency->rate); uint32 money_c = Clamp(ClampToI32(money), 0, 20000000); // Clamp between 20 million and 0 - DoCommandP(0, money_c, this->window_number, CMD_GIVE_MONEY | CMD_MSG(STR_ERROR_CAN_T_GIVE_MONEY)); + DoCommandP(CMD_GIVE_MONEY | CMD_MSG(STR_ERROR_CAN_T_GIVE_MONEY), 0, money_c, this->window_number); break; } case WID_C_PRESIDENT_NAME: - DoCommandP(0, 0, 0, CMD_RENAME_PRESIDENT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_PRESIDENT), nullptr, str); + DoCommandP(CMD_RENAME_PRESIDENT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_PRESIDENT), 0, 0, 0, str); break; case WID_C_COMPANY_NAME: - DoCommandP(0, 0, 0, CMD_RENAME_COMPANY | CMD_MSG(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME), nullptr, str); + DoCommandP(CMD_RENAME_COMPANY | CMD_MSG(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME), 0, 0, 0, str); break; case WID_C_COMPANY_JOIN: @@ -2771,7 +2771,7 @@ struct BuyCompanyWindow : Window { break; case WID_BC_YES: - DoCommandP(0, this->window_number, 0, CMD_BUY_COMPANY | CMD_MSG(STR_ERROR_CAN_T_BUY_COMPANY)); + DoCommandP(CMD_BUY_COMPANY | CMD_MSG(STR_ERROR_CAN_T_BUY_COMPANY), 0, this->window_number, 0); break; } } diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 5cdb744abc..040b938fe7 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -630,7 +630,7 @@ DEF_CONSOLE_CMD(ConPauseGame) } if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); if (!_networking) IConsolePrint(CC_DEFAULT, "Game paused."); } else { IConsolePrint(CC_DEFAULT, "Game is already paused."); @@ -652,7 +652,7 @@ DEF_CONSOLE_CMD(ConUnpauseGame) } if ((_pause_mode & PM_PAUSED_NORMAL) != PM_UNPAUSED) { - DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); if (!_networking) IConsolePrint(CC_DEFAULT, "Game unpaused."); } else if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED) { IConsolePrint(CC_DEFAULT, "Game is in error state and cannot be unpaused via console."); @@ -863,7 +863,7 @@ DEF_CONSOLE_CMD(ConResetCompany) } /* It is safe to remove this company */ - DoCommandP(0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0); IConsolePrint(CC_DEFAULT, "Company deleted."); return true; @@ -1220,7 +1220,7 @@ DEF_CONSOLE_CMD(ConStartAI) } /* Start a new AI company */ - DoCommandP(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | INVALID_COMPANY << 16, 0); return true; } @@ -1256,8 +1256,8 @@ DEF_CONSOLE_CMD(ConReloadAI) } /* First kill the company of the AI, then start a new one. This should start the current AI again */ - DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL); - DoCommandP(0, CCA_NEW_AI | company_id << 16, 0, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | company_id << 16, 0); IConsolePrint(CC_DEFAULT, "AI reloaded."); return true; @@ -1294,7 +1294,7 @@ DEF_CONSOLE_CMD(ConStopAI) } /* Now kill the company of the AI. */ - DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0); IConsolePrint(CC_DEFAULT, "AI stopped, company deleted."); return true; diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index d6f4d900cf..7ff812c230 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -141,7 +141,7 @@ static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Veh if (wagon == v) return; - DoCommandP(v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE)); + DoCommandP(CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE), v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index); } static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END]; ///< Cell size for vehicle images in the depot view. @@ -802,7 +802,7 @@ struct DepotWindow : Window { case WID_D_STOP_ALL: case WID_D_START_ALL: { VehicleListIdentifier vli(VL_DEPOT_LIST, this->type, this->owner); - DoCommandP(this->window_number, (widget == WID_D_START_ALL ? (1 << 0) : 0), vli.Pack(), CMD_MASS_START_STOP); + DoCommandP(CMD_MASS_START_STOP, this->window_number, (widget == WID_D_START_ALL ? (1 << 0) : 0), vli.Pack()); break; } @@ -825,7 +825,7 @@ struct DepotWindow : Window { break; case WID_D_AUTOREPLACE: - DoCommandP(this->window_number, this->type, 0, CMD_DEPOT_MASS_AUTOREPLACE); + DoCommandP(CMD_DEPOT_MASS_AUTOREPLACE, this->window_number, this->type, 0); break; } @@ -836,7 +836,7 @@ struct DepotWindow : Window { if (str == nullptr) return; /* Do depot renaming */ - DoCommandP(0, this->GetDepotIndex(), 0, CMD_RENAME_DEPOT | CMD_MSG(STR_ERROR_CAN_T_RENAME_DEPOT), nullptr, str); + DoCommandP(CMD_RENAME_DEPOT | CMD_MSG(STR_ERROR_CAN_T_RENAME_DEPOT), 0, this->GetDepotIndex(), 0, str); } bool OnRightClick(Point pt, int widget) override @@ -904,10 +904,10 @@ struct DepotWindow : Window { { if (_ctrl_pressed) { /* Share-clone, do not open new viewport, and keep tool active */ - DoCommandP(this->window_number, v->index, 1, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), nullptr); + DoCommandP(CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), this->window_number, v->index, 1); } else { /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to changs things on new vehicle) */ - if (DoCommandP(this->window_number, v->index, 0, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), CcCloneVehicle)) { + if (DoCommandP(CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), CcCloneVehicle, this->window_number, v->index, 0)) { ResetObjectToPlace(); } } @@ -1001,8 +1001,8 @@ struct DepotWindow : Window { if (this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, &gdvp) == MODE_DRAG_VEHICLE && sel != INVALID_VEHICLE) { if (gdvp.wagon != nullptr && gdvp.wagon->index == sel && _ctrl_pressed) { - DoCommandP(Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true, - CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE)); + DoCommandP(CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE), + Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true); } else if (gdvp.wagon == nullptr || gdvp.wagon->index != sel) { this->vehicle_over = INVALID_VEHICLE; TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head); @@ -1027,7 +1027,7 @@ struct DepotWindow : Window { this->SetDirty(); int sell_cmd = (v->type == VEH_TRAIN && (widget == WID_D_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0; - DoCommandP(v->tile, v->index | sell_cmd << 20 | MAKE_ORDER_BACKUP_FLAG, 0, GetCmdSellVeh(v->type)); + DoCommandP(GetCmdSellVeh(v->type), v->tile, v->index | sell_cmd << 20 | MAKE_ORDER_BACKUP_FLAG, 0); break; } @@ -1091,7 +1091,7 @@ static void DepotSellAllConfirmationCallback(Window *win, bool confirmed) DepotWindow *w = (DepotWindow*)win; TileIndex tile = w->window_number; byte vehtype = w->type; - DoCommandP(tile, vehtype, 0, CMD_DEPOT_SELL_ALL_VEHICLES); + DoCommandP(CMD_DEPOT_SELL_ALL_VEHICLES, tile, vehtype, 0); } } diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 77ebe1be78..0911555a4e 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -191,7 +191,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_LOCK: // Build lock button - DoCommandP(tile, 0, 0, CMD_BUILD_LOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_LOCKS), CcBuildDocks); + DoCommandP(CMD_BUILD_LOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_LOCKS), CcBuildDocks, tile, 0, 0); break; case WID_DT_DEMOLISH: // Demolish aka dynamite button @@ -199,7 +199,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_DEPOT: // Build depot button - DoCommandP(tile, _ship_depot_direction, 0, CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks); + DoCommandP(CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks, tile, _ship_depot_direction, 0); break; case WID_DT_STATION: { // Build station button @@ -217,7 +217,7 @@ struct BuildDocksToolbarWindow : Window { } case WID_DT_BUOY: // Build buoy button - DoCommandP(tile, 0, 0, CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE), CcBuildDocks); + DoCommandP(CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE), CcBuildDocks, tile, 0, 0); break; case WID_DT_RIVER: // Build river button (in scenario editor) @@ -225,7 +225,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button - DoCommandP(tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15, CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE), CcBuildBridge); + DoCommandP(CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE), CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15); break; default: NOT_REACHED(); @@ -245,10 +245,10 @@ struct BuildDocksToolbarWindow : Window { GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; case DDSP_CREATE_WATER: - DoCommandP(end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL, CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_BUILD_CANALS), CcPlaySound_CONSTRUCTION_WATER); + DoCommandP(CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_BUILD_CANALS), CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL); break; case DDSP_CREATE_RIVER: - DoCommandP(end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0), CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_PLACE_RIVERS), CcPlaySound_CONSTRUCTION_WATER); + DoCommandP(CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_PLACE_RIVERS), CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0)); break; default: break; diff --git a/src/economy.cpp b/src/economy.cpp index 5c25636454..b7100257a0 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -627,7 +627,7 @@ static void CompanyCheckBankrupt(Company *c) * player we are sure (the above check) that we are not the local * company and thus we won't be moved. */ if (!_networking || _network_server) { - DoCommandP(0, CCA_DELETE | (c->index << 16) | (CRR_BANKRUPT << 24), 0, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | (c->index << 16) | (CRR_BANKRUPT << 24), 0); return; } break; diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index bc0143be17..6710967f43 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -125,7 +125,7 @@ struct EnginePreviewWindow : Window { { switch (widget) { case WID_EP_YES: - DoCommandP(0, this->window_number, 0, CMD_WANT_ENGINE_PREVIEW); + DoCommandP(CMD_WANT_ENGINE_PREVIEW, 0, this->window_number, 0); FALLTHROUGH; case WID_EP_NO: if (!_shift_pressed) this->Close(); diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index c0551701e8..9d7ab70d8c 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -358,7 +358,7 @@ public: /* pause is only used in single-player, non-editor mode, non-menu mode. It * will be unpaused in the WE_DESTROY event handler. */ if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) { - DoCommandP(0, PM_PAUSED_SAVELOAD, 1, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 1); } SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); @@ -402,7 +402,7 @@ public: { /* pause is only used in single-player, non-editor mode, non menu mode */ if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) { - DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 0); } this->Window::Close(); } diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index 65ed9003b0..d6180b0df2 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -382,17 +382,17 @@ struct GoalQuestionWindow : public Window { { switch (widget) { case WID_GQ_BUTTON_1: - DoCommandP(0, this->window_number, this->button[0], CMD_GOAL_QUESTION_ANSWER); + DoCommandP(CMD_GOAL_QUESTION_ANSWER, 0, this->window_number, this->button[0]); this->Close(); break; case WID_GQ_BUTTON_2: - DoCommandP(0, this->window_number, this->button[1], CMD_GOAL_QUESTION_ANSWER); + DoCommandP(CMD_GOAL_QUESTION_ANSWER, 0, this->window_number, this->button[1]); this->Close(); break; case WID_GQ_BUTTON_3: - DoCommandP(0, this->window_number, this->button[2], CMD_GOAL_QUESTION_ANSWER); + DoCommandP(CMD_GOAL_QUESTION_ANSWER, 0, this->window_number, this->button[2]); this->Close(); break; } diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 374ed5700d..ee8e604744 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -640,7 +640,7 @@ public: if (confirmed) { VehicleGroupWindow *w = (VehicleGroupWindow*)win; w->vli.index = ALL_GROUP; - DoCommandP(0, w->group_confirm, 0, CMD_DELETE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_DELETE)); + DoCommandP(CMD_DELETE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_DELETE), 0, w->group_confirm, 0); } } @@ -771,7 +771,7 @@ public: } case WID_GL_CREATE_GROUP: { // Create a new group - DoCommandP(0, this->vli.vtype, this->vli.index, CMD_CREATE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_CREATE), CcCreateGroup); + DoCommandP(CMD_CREATE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_CREATE), CcCreateGroup, 0, this->vli.vtype, this->vli.index); break; } @@ -800,14 +800,14 @@ public: case WID_GL_START_ALL: case WID_GL_STOP_ALL: { // Start/stop all vehicles of the list - DoCommandP(0, (1 << 1) | (widget == WID_GL_START_ALL ? (1 << 0) : 0), this->vli.Pack(), CMD_MASS_START_STOP); + DoCommandP(CMD_MASS_START_STOP, 0, (1 << 1) | (widget == WID_GL_START_ALL ? (1 << 0) : 0), this->vli.Pack()); break; } case WID_GL_REPLACE_PROTECTION: { const Group *g = Group::GetIfValid(this->vli.index); if (g != nullptr) { - DoCommandP(0, this->vli.index | (GroupFlags::GF_REPLACE_PROTECTION << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG); + DoCommandP(CMD_SET_GROUP_FLAG, 0, this->vli.index | (GroupFlags::GF_REPLACE_PROTECTION << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION) ? 0 : 1) | (_ctrl_pressed << 1)); } break; } @@ -822,7 +822,7 @@ public: case WID_GL_ALL_VEHICLES: // All vehicles case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles if (g->parent != INVALID_GROUP) { - DoCommandP(0, this->group_sel | (1 << 16), INVALID_GROUP, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT)); + DoCommandP(CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT), 0, this->group_sel | (1 << 16), INVALID_GROUP); } this->group_sel = INVALID_GROUP; @@ -835,7 +835,7 @@ public: GroupID new_g = id_g >= this->groups.size() ? INVALID_GROUP : this->groups[id_g]->index; if (this->group_sel != new_g && g->parent != new_g) { - DoCommandP(0, this->group_sel | (1 << 16), new_g, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT)); + DoCommandP(CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT), 0, this->group_sel | (1 << 16), new_g); } this->group_sel = INVALID_GROUP; @@ -850,7 +850,7 @@ public: { switch (widget) { case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles - DoCommandP(0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE)); + DoCommandP(CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE), 0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); this->vehicle_sel = INVALID_VEHICLE; this->group_over = INVALID_GROUP; @@ -867,7 +867,7 @@ public: uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP); GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; - DoCommandP(0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE), new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr); + DoCommandP(CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE), new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); break; } @@ -922,7 +922,7 @@ public: void OnQueryTextFinished(char *str) override { - if (str != nullptr) DoCommandP(0, this->group_rename, 0, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), nullptr, str); + if (str != nullptr) DoCommandP(CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), 0, this->group_rename, 0, str); this->group_rename = INVALID_GROUP; } @@ -952,19 +952,19 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: { // Send to Depots - DoCommandP(0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack(), GetCmdSendToDepot(this->vli.vtype)); + DoCommandP(GetCmdSendToDepot(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack()); break; } case ADI_ADD_SHARED: // Add shared Vehicles assert(Group::IsValidID(this->vli.index)); - DoCommandP(0, this->vli.index, this->vli.vtype, CMD_ADD_SHARED_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE)); + DoCommandP(CMD_ADD_SHARED_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE), 0, this->vli.index, this->vli.vtype); break; case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group assert(Group::IsValidID(this->vli.index)); - DoCommandP(0, this->vli.index, 0, CMD_REMOVE_ALL_VEHICLES_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES)); + DoCommandP(CMD_REMOVE_ALL_VEHICLES_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES), 0, this->vli.index, 0); break; default: NOT_REACHED(); } diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index 768b9c9c17..0dfaebc3b7 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -96,7 +96,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { EndGameWindow(WindowDesc *desc) : EndGameHighScoreBaseWindow(desc) { /* Pause in single-player to have a look at the highscore at your own leisure */ - if (!_networking) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); + if (!_networking) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); this->background_img = SPR_TYCOON_IMG1_BEGIN; @@ -124,7 +124,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { void Close() override { - if (!_networking) DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); // unpause + if (!_networking) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); // unpause ShowHighscoreTable(this->window_number, this->rank); this->EndGameHighScoreBaseWindow::Close(); } @@ -159,7 +159,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { { /* pause game to show the chart */ this->game_paused_by_player = _pause_mode == PM_PAUSED_NORMAL; - if (!_networking && !this->game_paused_by_player) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); + if (!_networking && !this->game_paused_by_player) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); /* Close all always on-top windows to get a clean screen */ if (_game_mode != GM_MENU) HideVitalWindows(); @@ -174,7 +174,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { { if (_game_mode != GM_MENU) ShowVitalWindows(); - if (!_networking && !this->game_paused_by_player) DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); // unpause + if (!_networking && !this->game_paused_by_player) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); // unpause this->EndGameHighScoreBaseWindow::Close(); } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index bfdb308b66..e78b6853d3 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -678,7 +678,7 @@ public: case WID_DPI_FUND_WIDGET: { if (this->selected_type != INVALID_INDUSTRYTYPE) { if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && GetIndustrySpec(this->selected_type)->IsRawIndustry()) { - DoCommandP(0, this->selected_type, InteractiveRandom(), CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); + DoCommandP(CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), 0, this->selected_type, InteractiveRandom()); this->HandleButtonClick(WID_DPI_FUND_WIDGET); } else { HandlePlacePushButton(this, WID_DPI_FUND_WIDGET, SPR_CURSOR_INDUSTRY, HT_RECT); @@ -715,14 +715,13 @@ public: Backup old_generating_world(_generating_world, true, FILE_LINE); _ignore_restrictions = true; - DoCommandP(tile, (layout_index << 8) | this->selected_type, seed, - CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry); + DoCommandP(CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry, tile, (layout_index << 8) | this->selected_type, seed); cur_company.Restore(); old_generating_world.Restore(); _ignore_restrictions = false; } else { - success = DoCommandP(tile, (layout_index << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); + success = DoCommandP(CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), tile, (layout_index << 8) | this->selected_type, seed); } /* If an industry has been built, just reset the cursor and the system */ diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index ce28ec3d85..c4fc2d5f9c 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -173,7 +173,7 @@ void StateGameLoop_LinkGraphPauseControl() if (_pause_mode & PM_PAUSED_LINK_GRAPH) { /* We are paused waiting on a job, check the job every tick. */ if (!LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { - DoCommandP(0, PM_PAUSED_LINK_GRAPH, 0, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_LINK_GRAPH, 0); } } else if (_pause_mode == PM_UNPAUSED && _date_fract == LinkGraphSchedule::SPAWN_JOIN_TICK - 2 && @@ -181,7 +181,7 @@ void StateGameLoop_LinkGraphPauseControl() LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { /* Perform check two _date_fract ticks before we would join, to make * sure it also works in multiplayer. */ - DoCommandP(0, PM_PAUSED_LINK_GRAPH, 1, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_LINK_GRAPH, 1); } } diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 6131050cf8..46fff1a51b 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -326,7 +326,7 @@ struct MainWindow : Window case GHK_MONEY: // Gimme money /* You can only cheat for money in singleplayer mode. */ - if (!_networking) DoCommandP(0, 10000000, 0, CMD_MONEY_CHEAT); + if (!_networking) DoCommandP(CMD_MONEY_CHEAT, 0, 10000000, 0); break; case GHK_UPDATE_COORDS: // Update the coordinates of all station signs diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index e60717cf89..c461d36dc8 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -134,7 +134,7 @@ CommandCost CmdDecreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint static void AskUnsafeUnpauseCallback(Window *w, bool confirmed) { if (confirmed) { - DoCommandP(0, PM_PAUSED_ERROR, 0, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_ERROR, 0); } } diff --git a/src/network/network.cpp b/src/network/network.cpp index dd0a915949..6e111926ed 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -394,7 +394,7 @@ static void CheckPauseHelper(bool pause, PauseMode pm) { if (pause == ((_pause_mode & pm) != PM_UNPAUSED)) return; - DoCommandP(0, pm, pause ? 1 : 0, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, pm, pause ? 1 : 0); } /** @@ -1064,7 +1064,7 @@ void NetworkGameLoop() while (f != nullptr && !feof(f)) { if (_date == next_date && _date_fract == next_date_fract) { if (cp != nullptr) { - NetworkSendCommand(cp->tile, cp->p1, cp->p2, cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->text, cp->company); + NetworkSendCommand(cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->company, cp->tile, cp->p1, cp->p2, cp->text); Debug(desync, 0, "Injecting: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text, GetCommandName(cp->cmd)); delete cp; cp = nullptr; diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index f03601b39f..e638df0053 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -839,7 +839,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet * the server will give us a client-id and let us in */ _network_join_status = NETWORK_JOIN_STATUS_REGISTERING; ShowJoinStatusWindow(); - NetworkSendCommand(0, CCA_NEW, 0, CMD_COMPANY_CTRL, nullptr, {}, _local_company); + NetworkSendCommand(CMD_COMPANY_CTRL, nullptr, _local_company, 0, CCA_NEW, 0, {}); } } else { /* take control over an existing company */ diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 6d03aaaa13..f1a0f682d3 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -125,15 +125,15 @@ static CommandQueue _local_execution_queue; /** * Prepare a DoCommand to be send over the network + * @param cmd The command to execute (a CMD_* value) + * @param callback A callback function to call after the command is finished + * @param company The company that wants to send the command * @param tile The tile to perform a command on (see #CommandProc) * @param p1 Additional data for the command (see #CommandProc) * @param p2 Additional data for the command (see #CommandProc) - * @param cmd The command to execute (a CMD_* value) - * @param callback A callback function to call after the command is finished * @param text The text to pass - * @param company The company that wants to send the command */ -void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, CompanyID company) +void NetworkSendCommand(uint32 cmd, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { assert((cmd & CMD_FLAGS_MASK) == 0); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 76385a087d..c795e15501 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1395,7 +1395,7 @@ static void AdminCompanyResetCallback(Window *w, bool confirmed) { if (confirmed) { if (NetworkCompanyHasClients(_admin_company_id)) return; - DoCommandP(0, CCA_DELETE | _admin_company_id << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | _admin_company_id << 16 | CRR_MANUAL << 24, 0); } } @@ -1535,9 +1535,9 @@ private: static void OnClickCompanyNew(NetworkClientListWindow *w, Point pt, CompanyID company_id) { if (_network_server) { - DoCommandP(0, CCA_NEW, _network_own_client_id, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW, _network_own_client_id); } else { - NetworkSendCommand(0, CCA_NEW, 0, CMD_COMPANY_CTRL, nullptr, {}, _local_company); + NetworkSendCommand(CMD_COMPANY_CTRL, nullptr, _local_company, 0, CCA_NEW, 0, {}); } } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 9deaa5522d..65e8010736 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1553,7 +1553,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_unprotected-months, and is there no protection? */ if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) { /* Shut the company down */ - DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0); IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no password.", c->index + 1); } /* Is the company empty for autoclean_protected-months, and there is a protection? */ @@ -1567,7 +1567,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_novehicles-months, and has no vehicles? */ if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) { /* Shut the company down */ - DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL); + DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0); IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no vehicles.", c->index + 1); } } else { @@ -2078,7 +2078,7 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci) /* ci is nullptr when replaying, or for AIs. In neither case there is a client. */ ci->client_playas = c->index; NetworkUpdateClientInfo(ci->client_id); - NetworkSendCommand(0, 0, 0, CMD_RENAME_PRESIDENT, nullptr, ci->client_name, c->index); + NetworkSendCommand(CMD_RENAME_PRESIDENT, nullptr, c->index, 0, 0, 0, ci->client_name); } /* Announce new company on network. */ diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 4ab9615337..b05d46831b 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -541,8 +541,8 @@ public: void OnPlaceObject(Point pt, TileIndex tile) override { ObjectClass *objclass = ObjectClass::Get(_selected_object_class); - DoCommandP(tile, objclass->GetSpec(_selected_object_index)->Index(), - _selected_object_view, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform); + DoCommandP(CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform, + tile, objclass->GetSpec(_selected_object_index)->Index(), _selected_object_view); } void OnPlaceObjectAbort() override diff --git a/src/openttd.cpp b/src/openttd.cpp index 189010aad1..abd5d99df6 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -851,7 +851,7 @@ static void MakeNewGameDone() /* In a dedicated server, the server does not play */ if (!VideoDriver::GetInstance()->HasGUI()) { OnStartGame(true); - if (_settings_client.gui.pause_on_newgame) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); + if (_settings_client.gui.pause_on_newgame) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); return; } @@ -880,7 +880,7 @@ static void MakeNewGameDone() NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass); } - if (_settings_client.gui.pause_on_newgame) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); + if (_settings_client.gui.pause_on_newgame) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); CheckEngines(); CheckIndustries(); @@ -1045,7 +1045,7 @@ void SwitchToMode(SwitchMode new_mode) } OnStartGame(_network_dedicated); /* Decrease pause counter (was increased from opening load dialog) */ - DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 0); } break; } @@ -1067,7 +1067,7 @@ void SwitchToMode(SwitchMode new_mode) SetLocalCompany(OWNER_NONE); _settings_newgame.game_creation.starting_year = _cur_year; /* Cancel the saveload pausing */ - DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 0); } else { SetDParamStr(0, GetSaveLoadErrorString()); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 8b8c2685f6..e3bcb30eb5 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -169,7 +169,7 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, /* If it's not a backup of us, ignore it. */ if (ob->user != user) continue; - DoCommandP(0, 0, user, CMD_CLEAR_ORDER_BACKUP); + DoCommandP(CMD_CLEAR_ORDER_BACKUP, 0, 0, user); return; } } @@ -198,7 +198,7 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, /* We need to circumvent the "prevention" from this command being executed * while the game is paused, so use the internal method. Nor do we want * this command to get its cost estimated when shift is pressed. */ - DoCommandPInternal(ob->tile, 0, user, CMD_CLEAR_ORDER_BACKUP, nullptr, {}, true, false); + DoCommandPInternal(CMD_CLEAR_ORDER_BACKUP, nullptr, true, false, ob->tile, 0, user, {}); } else { /* The command came from the game logic, i.e. the clearing of a tile. * In that case we have no need to actually sync this, just do it. */ diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 3205be166f..8ec4e7e985 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -591,7 +591,7 @@ private: } if (order->GetLoadType() == load_type) return; // If we still match, do nothing - DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (load_type << 4), CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); + DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (load_type << 4)); } /** @@ -606,7 +606,7 @@ private: if (order == nullptr) return; i = (order->GetDepotOrderType() & ODTFB_SERVICE) ? DA_ALWAYS_GO : DA_SERVICE; } - DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4), CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); + DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4)); } /** @@ -621,7 +621,7 @@ private: _settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); order.SetDepotActionType(ODATFB_NEAREST_DEPOT); - DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER)); + DoCommandP(CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); } /** @@ -641,11 +641,11 @@ private: } if (order->GetUnloadType() == unload_type) return; // If we still match, do nothing - DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4), CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); + DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4)); /* Transfer and unload orders with leave empty as default */ if (unload_type == OUFB_TRANSFER || unload_type == OUFB_UNLOAD) { - DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (OLFB_NO_LOAD << 4), CMD_MODIFY_ORDER); + DoCommandP(CMD_MODIFY_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (OLFB_NO_LOAD << 4)); this->SetWidgetDirty(WID_O_FULL_LOAD); } } @@ -669,7 +669,7 @@ private: } this->SetWidgetDirty(WID_O_NON_STOP); - DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_NON_STOP | non_stop << 4, CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); + DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_NON_STOP | non_stop << 4); } /** @@ -682,8 +682,8 @@ private: if (_ctrl_pressed && this->vehicle->cur_implicit_order_index == this->OrderGetSel()) return; if (this->vehicle->GetNumOrders() <= 1) return; - DoCommandP(this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders()), - CMD_SKIP_TO_ORDER | CMD_MSG(_ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER)); + DoCommandP(CMD_SKIP_TO_ORDER | CMD_MSG(_ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER), + this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders())); } /** @@ -694,7 +694,7 @@ private: /* When networking, move one order lower */ int selected = this->selected_order + (int)_networking; - if (DoCommandP(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CMD_DELETE_ORDER | CMD_MSG(STR_ERROR_CAN_T_DELETE_THIS_ORDER))) { + if (DoCommandP(CMD_DELETE_ORDER | CMD_MSG(STR_ERROR_CAN_T_DELETE_THIS_ORDER), this->vehicle->tile, this->vehicle->index, this->OrderGetSel())) { this->selected_order = selected >= this->vehicle->GetNumOrders() ? -1 : selected; this->UpdateButtonState(); } @@ -719,7 +719,7 @@ private: /* Get another vehicle that share orders with this vehicle. */ Vehicle *other_shared = (this->vehicle->FirstShared() == this->vehicle) ? this->vehicle->NextShared() : this->vehicle->PreviousShared(); /* Copy the order list of the other vehicle. */ - if (DoCommandP(this->vehicle->tile, this->vehicle->index | CO_COPY << 30, other_shared->index, CMD_CLONE_ORDER | CMD_MSG(STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST))) { + if (DoCommandP(CMD_CLONE_ORDER | CMD_MSG(STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST), this->vehicle->tile, this->vehicle->index | CO_COPY << 30, other_shared->index)) { this->UpdateButtonState(); } } @@ -734,10 +734,10 @@ private: { if (_ctrl_pressed) { /* Cancel refitting */ - DoCommandP(this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT, CMD_ORDER_REFIT); + DoCommandP(CMD_ORDER_REFIT, this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT); } else { if (i == 1) { // Auto-refit to available cargo type. - DoCommandP(this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | CT_AUTO_REFIT, CMD_ORDER_REFIT); + DoCommandP(CMD_ORDER_REFIT, this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | CT_AUTO_REFIT); } else { ShowVehicleRefitWindow(this->vehicle, this->OrderGetSel(), this, auto_refit); } @@ -1159,7 +1159,7 @@ public: order.index = 0; order.MakeConditional(order_id); - DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER)); + DoCommandP(CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); } ResetObjectToPlace(); break; @@ -1182,9 +1182,9 @@ public: this->selected_order = -1; } else if (sel == this->selected_order) { if (this->vehicle->type == VEH_TRAIN && sel < this->vehicle->GetNumOrders()) { - DoCommandP(this->vehicle->tile, this->vehicle->index + (sel << 20), - MOF_STOP_LOCATION | ((this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END) << 4, - CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); + DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), + this->vehicle->tile, this->vehicle->index + (sel << 20), + MOF_STOP_LOCATION | ((this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END) << 4); } } else { /* Select clicked order */ @@ -1331,7 +1331,7 @@ public: default: break; } - DoCommandP(this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4, CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); + DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4); } } @@ -1369,11 +1369,11 @@ public: break; case WID_O_COND_VARIABLE: - DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VARIABLE | index << 4, CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); + DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VARIABLE | index << 4); break; case WID_O_COND_COMPARATOR: - DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_COMPARATOR | index << 4, CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); + DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_COMPARATOR | index << 4); break; } } @@ -1386,7 +1386,7 @@ public: VehicleOrderID to_order = this->GetOrderFromPt(pt.y); if (!(from_order == to_order || from_order == INVALID_VEH_ORDER_ID || from_order > this->vehicle->GetNumOrders() || to_order == INVALID_VEH_ORDER_ID || to_order > this->vehicle->GetNumOrders()) && - DoCommandP(this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16), CMD_MOVE_ORDER | CMD_MSG(STR_ERROR_CAN_T_MOVE_THIS_ORDER))) { + DoCommandP(CMD_MOVE_ORDER | CMD_MSG(STR_ERROR_CAN_T_MOVE_THIS_ORDER), this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16))) { this->selected_order = -1; this->UpdateButtonState(); } @@ -1438,7 +1438,7 @@ public: const Order cmd = GetOrderCmdFromTile(this->vehicle, tile); if (cmd.IsType(OT_NOTHING)) return; - if (DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) { + if (DoCommandP(CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack())) { /* With quick goto the Go To button stays active */ if (!_settings_client.gui.quick_goto) ResetObjectToPlace(); } @@ -1455,8 +1455,8 @@ public: bool share_order = _ctrl_pressed || this->goto_type == OPOS_SHARE; if (this->vehicle->GetNumOrders() != 0 && !share_order) return false; - if (DoCommandP(this->vehicle->tile, this->vehicle->index | (share_order ? CO_SHARE : CO_COPY) << 30, v->index, - share_order ? CMD_CLONE_ORDER | CMD_MSG(STR_ERROR_CAN_T_SHARE_ORDER_LIST) : CMD_CLONE_ORDER | CMD_MSG(STR_ERROR_CAN_T_COPY_ORDER_LIST))) { + if (DoCommandP(share_order ? CMD_CLONE_ORDER | CMD_MSG(STR_ERROR_CAN_T_SHARE_ORDER_LIST) : CMD_CLONE_ORDER | CMD_MSG(STR_ERROR_CAN_T_COPY_ORDER_LIST), + this->vehicle->tile, this->vehicle->index | (share_order ? CO_SHARE : CO_COPY) << 30, v->index)) { this->selected_order = -1; ResetObjectToPlace(); } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 9ed9032c45..17254ccfb0 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -92,11 +92,11 @@ void CcPlaySound_CONSTRUCTION_RAIL(const CommandCost &result, TileIndex tile, ui static void GenericPlaceRail(TileIndex tile, int cmd) { - DoCommandP(tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3), - _remove_button_clicked ? + DoCommandP(_remove_button_clicked ? CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) : CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), - CcPlaySound_CONSTRUCTION_RAIL); + CcPlaySound_CONSTRUCTION_RAIL, + tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3)); } /** @@ -112,7 +112,7 @@ static void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track) if (GetRailTileType(tile) == RAIL_TILE_SIGNALS && !_settings_client.gui.auto_remove_signals) return; if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) return; - DoCommandP(tile, _cur_railtype, track | (_settings_client.gui.auto_remove_signals << 3), CMD_BUILD_SINGLE_RAIL); + DoCommandP(CMD_BUILD_SINGLE_RAIL, tile, _cur_railtype, track | (_settings_client.gui.auto_remove_signals << 3)); } /** Additional pieces of track to add at the entrance of a depot. */ @@ -166,7 +166,7 @@ static void PlaceRail_Waypoint(TileIndex tile) } else { /* Tile where we can't build rail waypoints. This is always going to fail, * but provides the user with a proper error message. */ - DoCommandP(tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT)); + DoCommandP(CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT), tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16); } } @@ -224,7 +224,7 @@ static void GenericPlaceSignals(TileIndex tile) Track track = FindFirstTrack(trackbits); if (_remove_button_clicked) { - DoCommandP(tile, track, 0, CMD_REMOVE_SIGNALS | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM), CcPlaySound_CONSTRUCTION_RAIL); + DoCommandP(CMD_REMOVE_SIGNALS | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM), CcPlaySound_CONSTRUCTION_RAIL, tile, track, 0); } else { const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0); @@ -255,9 +255,8 @@ static void GenericPlaceSignals(TileIndex tile) SB(p1, 9, 6, cycle_types); } - DoCommandP(tile, p1, 0, CMD_BUILD_SIGNALS | - CMD_MSG((w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE), - CcPlaySound_CONSTRUCTION_RAIL); + DoCommandP(CMD_BUILD_SIGNALS | CMD_MSG((w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE), + CcPlaySound_CONSTRUCTION_RAIL, tile, p1, 0); } } @@ -359,11 +358,11 @@ static void BuildRailClick_Remove(Window *w) static void DoRailroadTrack(int mode) { uint32 p2 = _cur_railtype | (mode << 6) | (_settings_client.gui.auto_remove_signals << 11); - DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, - _remove_button_clicked ? + DoCommandP(_remove_button_clicked ? CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) : CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), - CcPlaySound_CONSTRUCTION_RAIL); + CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2); } static void HandleAutodirPlacement() @@ -414,11 +413,11 @@ static void HandleAutoSignalPlacement() /* _settings_client.gui.drag_signals_density is given as a parameter such that each user * in a network game can specify their own signal density */ - DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, - _remove_button_clicked ? + DoCommandP(_remove_button_clicked ? CMD_REMOVE_SIGNAL_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM) : CMD_BUILD_SIGNAL_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE), - CcPlaySound_CONSTRUCTION_RAIL); + CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2); } @@ -644,9 +643,8 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_DEPOT: - DoCommandP(tile, _cur_railtype, _build_depot_direction, - CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT), - CcRailDepot); + DoCommandP(CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT), + CcRailDepot, tile, _cur_railtype, _build_depot_direction); break; case WID_RAT_BUILD_WAYPOINT: @@ -666,7 +664,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_TUNNEL: - DoCommandP(tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel); + DoCommandP(CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0); break; case WID_RAT_CONVERT_RAIL: @@ -708,7 +706,7 @@ struct BuildRailToolbarWindow : Window { break; case DDSP_CONVERT_RAIL: - DoCommandP(end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0), CMD_CONVERT_RAIL | CMD_MSG(STR_ERROR_CAN_T_CONVERT_RAIL), CcPlaySound_CONSTRUCTION_RAIL); + DoCommandP(CMD_CONVERT_RAIL | CMD_MSG(STR_ERROR_CAN_T_CONVERT_RAIL), CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0)); break; case DDSP_REMOVE_STATION: @@ -716,14 +714,14 @@ struct BuildRailToolbarWindow : Window { if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) { /* Station */ if (_remove_button_clicked) { - DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION), CcPlaySound_CONSTRUCTION_RAIL); + DoCommandP(CMD_REMOVE_FROM_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION), CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); } else { HandleStationPlacement(start_tile, end_tile); } } else { /* Waypoint */ if (_remove_button_clicked) { - DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT), CcPlaySound_CONSTRUCTION_RAIL); + DoCommandP(CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT), CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); } else { TileArea ta(start_tile, end_tile); uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 6 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24; diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 30d9301aab..84ec742068 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -124,7 +124,7 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) /* if there is a roadpiece just outside of the station entrance, build a connecting route */ if (IsNormalRoadTile(tile)) { if (GetRoadBits(tile, GetRoadTramType(_cur_roadtype)) != ROAD_NONE) { - DoCommandP(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, CMD_BUILD_ROAD); + DoCommandP(CMD_BUILD_ROAD, tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0); } } } @@ -550,8 +550,8 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_DEPOT: - DoCommandP(tile, _cur_roadtype << 2 | _road_depot_orientation, 0, - CMD_BUILD_ROAD_DEPOT | CMD_MSG(this->rti->strings.err_depot), CcRoadDepot); + DoCommandP(CMD_BUILD_ROAD_DEPOT | CMD_MSG(this->rti->strings.err_depot), CcRoadDepot, + tile, _cur_roadtype << 2 | _road_depot_orientation, 0); break; case WID_ROT_BUS_STATION: @@ -567,8 +567,8 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_BUILD_TUNNEL: - DoCommandP(tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, - CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel); + DoCommandP(CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel, + tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0); break; case WID_ROT_CONVERT_ROAD: @@ -669,10 +669,10 @@ struct BuildRoadToolbarWindow : Window { * flags */ _place_road_flag = (RoadFlags)((_place_road_flag & RF_DIR_Y) ? (_place_road_flag & 0x07) : (_place_road_flag >> 3)); - DoCommandP(start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10), - _remove_button_clicked ? + DoCommandP(_remove_button_clicked ? CMD_REMOVE_LONG_ROAD | CMD_MSG(this->rti->strings.err_remove_road) : - CMD_BUILD_LONG_ROAD | CMD_MSG(this->rti->strings.err_build_road), CcPlaySound_CONSTRUCTION_OTHER); + CMD_BUILD_LONG_ROAD | CMD_MSG(this->rti->strings.err_build_road), CcPlaySound_CONSTRUCTION_OTHER, + start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10)); break; case DDSP_BUILD_BUSSTOP: @@ -680,7 +680,7 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_BUS_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS, CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_BUS]), CcPlaySound_CONSTRUCTION_OTHER); + DoCommandP(CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_BUS]), CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS); } else { PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(this->rti->strings.err_build_station[ROADSTOP_BUS])); } @@ -692,7 +692,7 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_CONSTRUCTION_OTHER); + DoCommandP(CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK); } else { PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP | CMD_MSG(this->rti->strings.err_build_station[ROADSTOP_TRUCK])); } @@ -700,7 +700,7 @@ struct BuildRoadToolbarWindow : Window { break; case DDSP_CONVERT_ROAD: - DoCommandP(end_tile, start_tile, _cur_roadtype, CMD_CONVERT_ROAD | CMD_MSG(rti->strings.err_convert_road), CcPlaySound_CONSTRUCTION_OTHER); + DoCommandP(CMD_CONVERT_ROAD | CMD_MSG(rti->strings.err_convert_road), CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype); break; } } diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index 1e20b55ed5..bb7260d9c5 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -329,7 +329,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() if (!estimate_only && _networking && !_generating_world) SetLastCommand(tile, p1, p2, cmd); /* Try to perform the command. */ - CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, command_text, false, estimate_only); + CommandCost res = ::DoCommandPInternal(cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, false, estimate_only, tile, p1, p2, command_text); /* We failed; set the error and bail out */ if (res.Failed()) { diff --git a/src/settings.cpp b/src/settings.cpp index 52f30be082..d821239fbb 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1549,7 +1549,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) const IntSettingDesc *setting = sd->AsIntSetting(); if ((setting->flags & SF_PER_COMPANY) != 0) { if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) { - return DoCommandP(0, 0, value, CMD_CHANGE_COMPANY_SETTING, nullptr, setting->GetName()); + return DoCommandP(CMD_CHANGE_COMPANY_SETTING, 0, 0, value, setting->GetName()); } setting->ChangeValue(&_settings_client.company, value); @@ -1575,7 +1575,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) /* send non-company-based settings over the network */ if (!_networking || (_networking && _network_server)) { - return DoCommandP(0, 0, value, CMD_CHANGE_SETTING, nullptr, setting->GetName()); + return DoCommandP(CMD_CHANGE_SETTING, 0, 0, value, setting->GetName()); } return false; } @@ -1603,7 +1603,7 @@ void SyncCompanySettings() const SettingDesc *sd = GetSettingDesc(desc); uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object); uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object); - if (old_value != new_value) NetworkSendCommand(0, 0, new_value, CMD_CHANGE_COMPANY_SETTING, nullptr, sd->GetName(), _local_company); + if (old_value != new_value) NetworkSendCommand(CMD_CHANGE_COMPANY_SETTING, nullptr, _local_company, 0, 0, new_value, sd->GetName()); } } diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index 78bbb8b4b5..77c5ce456c 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -130,5 +130,5 @@ void CcPlaceSign(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 */ void PlaceProc_Sign(TileIndex tile) { - DoCommandP(tile, 0, 0, CMD_PLACE_SIGN | CMD_MSG(STR_ERROR_CAN_T_PLACE_SIGN_HERE), CcPlaceSign); + DoCommandP(CMD_PLACE_SIGN | CMD_MSG(STR_ERROR_CAN_T_PLACE_SIGN_HERE), CcPlaceSign, tile, 0, 0); } diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 5169064625..368b57b43e 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -413,7 +413,7 @@ Window *ShowSignList() static bool RenameSign(SignID index, const char *text) { bool remove = StrEmpty(text); - DoCommandP(0, index, 0, CMD_RENAME_SIGN | (StrEmpty(text) ? CMD_MSG(STR_ERROR_CAN_T_DELETE_SIGN) : CMD_MSG(STR_ERROR_CAN_T_CHANGE_SIGN_NAME)), nullptr, text); + DoCommandP(CMD_RENAME_SIGN | (StrEmpty(text) ? CMD_MSG(STR_ERROR_CAN_T_DELETE_SIGN) : CMD_MSG(STR_ERROR_CAN_T_CHANGE_SIGN_NAME)), 0, index, 0, text); return remove; } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index ecc7ea77c3..1992a2c56c 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -1947,7 +1947,7 @@ struct StationViewWindow : public Window { break; case WID_SV_CLOSE_AIRPORT: - DoCommandP(0, this->window_number, 0, CMD_OPEN_CLOSE_AIRPORT); + DoCommandP(CMD_OPEN_CLOSE_AIRPORT, 0, this->window_number, 0); break; case WID_SV_TRAINS: // Show list of scheduled trains to this station @@ -2084,7 +2084,7 @@ struct StationViewWindow : public Window { { if (str == nullptr) return; - DoCommandP(0, this->window_number, 0, CMD_RENAME_STATION | CMD_MSG(STR_ERROR_CAN_T_RENAME_STATION), nullptr, str); + DoCommandP(CMD_RENAME_STATION | CMD_MSG(STR_ERROR_CAN_T_RENAME_STATION), 0, this->window_number, 0, str); } void OnResize() override diff --git a/src/story_gui.cpp b/src/story_gui.cpp index ccb9ccf7b8..5330b8a304 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -566,7 +566,7 @@ protected: this->SetTimeout(); this->SetWidgetDirty(WID_SB_PAGE_PANEL); - DoCommandP(0, pe.index, 0, CMD_STORY_PAGE_BUTTON); + DoCommandP(CMD_STORY_PAGE_BUTTON, 0, pe.index, 0); break; case SPET_BUTTON_TILE: @@ -921,7 +921,7 @@ public: return; } - DoCommandP(tile, pe->index, 0, CMD_STORY_PAGE_BUTTON); + DoCommandP(CMD_STORY_PAGE_BUTTON, tile, pe->index, 0); ResetObjectToPlace(); } @@ -940,7 +940,7 @@ public: VehicleType wanted_vehtype = data.GetVehicleType(); if (wanted_vehtype != VEH_INVALID && wanted_vehtype != v->type) return false; - DoCommandP(0, pe->index, v->index, CMD_STORY_PAGE_BUTTON); + DoCommandP(CMD_STORY_PAGE_BUTTON, 0, pe->index, v->index); ResetObjectToPlace(); return true; } diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 820287e9ce..5e25df78ca 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -60,7 +60,7 @@ static void GenerateDesertArea(TileIndex end, TileIndex start) TileArea ta(start, end); for (TileIndex tile : ta) { SetTropicZone(tile, (_ctrl_pressed) ? TROPICZONE_NORMAL : TROPICZONE_DESERT); - DoCommandP(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + DoCommandP(CMD_LANDSCAPE_CLEAR, tile, 0, 0); MarkTileDirtyByTile(tile); } old_generating_world.Restore(); @@ -115,16 +115,16 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t switch (proc) { case DDSP_DEMOLISH_AREA: - DoCommandP(end_tile, start_tile, _ctrl_pressed ? 1 : 0, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION); + DoCommandP(CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed ? 1 : 0); break; case DDSP_RAISE_AND_LEVEL_AREA: - DoCommandP(end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0), CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_RAISE_LAND_HERE), CcTerraform); + DoCommandP(CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_RAISE_LAND_HERE), CcTerraform, end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0)); break; case DDSP_LOWER_AND_LEVEL_AREA: - DoCommandP(end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0), CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_LOWER_LAND_HERE), CcTerraform); + DoCommandP(CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_LOWER_LAND_HERE), CcTerraform, end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0)); break; case DDSP_LEVEL_AREA: - DoCommandP(end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0), CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_LEVEL_LAND_HERE), CcTerraform); + DoCommandP(CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_LEVEL_LAND_HERE), CcTerraform, end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0)); break; case DDSP_CREATE_ROCKS: GenerateRockyArea(end_tile, start_tile); @@ -238,7 +238,7 @@ struct TerraformToolbarWindow : Window { break; case WID_TT_BUY_LAND: // Buy land button - DoCommandP(tile, OBJECT_OWNED_LAND, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound_CONSTRUCTION_RAIL); + DoCommandP(CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0); break; case WID_TT_PLACE_SIGN: // Place sign button @@ -395,7 +395,7 @@ static void CommonRaiseLowerBigLand(TileIndex tile, int mode) StringID msg = mode ? STR_ERROR_CAN_T_RAISE_LAND_HERE : STR_ERROR_CAN_T_LOWER_LAND_HERE; - DoCommandP(tile, SLOPE_N, (uint32)mode, CMD_TERRAFORM_LAND | CMD_MSG(msg), CcTerraform); + DoCommandP(CMD_TERRAFORM_LAND | CMD_MSG(msg), CcTerraform, tile, SLOPE_N, (uint32)mode); } else { assert(_terraform_size != 0); TileArea ta(tile, _terraform_size, _terraform_size); @@ -422,7 +422,7 @@ static void CommonRaiseLowerBigLand(TileIndex tile, int mode) for (TileIndex tile2 : ta) { if (TileHeight(tile2) == h) { - DoCommandP(tile2, SLOPE_N, (uint32)mode, CMD_TERRAFORM_LAND); + DoCommandP(CMD_TERRAFORM_LAND, tile2, SLOPE_N, (uint32)mode); } } } diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 4853181b31..9f9bfad5a6 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -142,7 +142,7 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID */ static void ChangeTimetableStartCallback(const Window *w, Date date) { - DoCommandP(0, w->window_number, date, CMD_SET_TIMETABLE_START | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); + DoCommandP(CMD_SET_TIMETABLE_START | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, w->window_number, date); } @@ -578,25 +578,25 @@ struct TimetableWindow : Window { case WID_VT_CLEAR_TIME: { // Clear waiting time. uint32 p1 = PackTimetableArgs(v, this->sel_index, false); - DoCommandP(0, p1, 0, CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); + DoCommandP(CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, p1, 0); break; } case WID_VT_CLEAR_SPEED: { // Clear max speed button. uint32 p1 = PackTimetableArgs(v, this->sel_index, true); - DoCommandP(0, p1, UINT16_MAX, CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); + DoCommandP(CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, p1, UINT16_MAX); break; } case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter. - DoCommandP(0, v->index, 0, CMD_SET_VEHICLE_ON_TIME | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); + DoCommandP(CMD_SET_VEHICLE_ON_TIME | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, v->index, 0); break; case WID_VT_AUTOFILL: { // Autofill the timetable. uint32 p2 = 0; if (!HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(p2, 0); if (_ctrl_pressed) SetBit(p2, 1); - DoCommandP(0, v->index, p2, CMD_AUTOFILL_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); + DoCommandP(CMD_AUTOFILL_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, v->index, p2); break; } @@ -629,7 +629,7 @@ struct TimetableWindow : Window { uint32 p2 = std::min(val, UINT16_MAX); - DoCommandP(0, p1, p2, CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); + DoCommandP(CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, p1, p2); } void OnResize() override diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index f5b3fa3b7d..665556e8ab 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -265,7 +265,7 @@ static CallBackFunction ToolbarPauseClick(Window *w) { if (_networking && !_network_server) return CBF_NONE; // only server can pause the game - if (DoCommandP(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, CMD_PAUSE)) { + if (DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED)) { if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); } return CBF_NONE; diff --git a/src/town_gui.cpp b/src/town_gui.cpp index a4bb240637..9082fc7b38 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -287,7 +287,7 @@ public: } case WID_TA_EXECUTE: - DoCommandP(this->town->xy, this->window_number, this->sel_index, CMD_DO_TOWN_ACTION | CMD_MSG(STR_ERROR_CAN_T_DO_THIS)); + DoCommandP(CMD_DO_TOWN_ACTION | CMD_MSG(STR_ERROR_CAN_T_DO_THIS), this->town->xy, this->window_number, this->sel_index); break; } } @@ -474,12 +474,12 @@ public: _warn_town_no_roads = true; } - DoCommandP(0, this->window_number, 0, CMD_EXPAND_TOWN | CMD_MSG(STR_ERROR_CAN_T_EXPAND_TOWN)); + DoCommandP(CMD_EXPAND_TOWN | CMD_MSG(STR_ERROR_CAN_T_EXPAND_TOWN), 0, this->window_number, 0); break; } case WID_TV_DELETE: // delete town - only available on Scenario editor - DoCommandP(0, this->window_number, 0, CMD_DELETE_TOWN | CMD_MSG(STR_ERROR_TOWN_CAN_T_DELETE)); + DoCommandP(CMD_DELETE_TOWN | CMD_MSG(STR_ERROR_TOWN_CAN_T_DELETE), 0, this->window_number, 0); break; } } @@ -561,7 +561,7 @@ public: { if (str == nullptr) return; - DoCommandP(0, this->window_number, 0, CMD_RENAME_TOWN | CMD_MSG(STR_ERROR_CAN_T_RENAME_TOWN), nullptr, str); + DoCommandP(CMD_RENAME_TOWN | CMD_MSG(STR_ERROR_CAN_T_RENAME_TOWN), 0, this->window_number, 0, str); } }; @@ -1162,8 +1162,8 @@ public: if (strcmp(buf, this->townname_editbox.text.buf) != 0) name = this->townname_editbox.text.buf; } - bool success = DoCommandP(tile, this->town_size | this->city << 2 | this->town_layout << 3 | random << 6, - townnameparts, CMD_FOUND_TOWN | CMD_MSG(errstr), cc, name); + bool success = DoCommandP(CMD_FOUND_TOWN | CMD_MSG(errstr), cc, + tile, this->town_size | this->city << 2 | this->town_layout << 3 | random << 6, townnameparts, name); /* Rerandomise name, if success and no cost-estimation. */ if (success && !_shift_pressed) this->RandomTownName(); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 775b1f6374..e0a70d14fb 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -86,7 +86,7 @@ void CheckTrainsLengths() if (!_networking && first) { first = false; - DoCommandP(0, PM_PAUSED_ERROR, 1, CMD_PAUSE); + DoCommandP(CMD_PAUSE, 0, PM_PAUSED_ERROR, 1); } /* Break so we warn only once for each train. */ break; diff --git a/src/train_gui.cpp b/src/train_gui.cpp index c8995f9b74..9bb7d59476 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -44,7 +44,7 @@ void CcBuildWagon(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p if (found != nullptr) { found = found->Last(); /* put the new wagon at the end of the loco. */ - DoCommandP(0, _new_vehicle_id, found->index, CMD_MOVE_RAIL_VEHICLE); + DoCommandP(CMD_MOVE_RAIL_VEHICLE, 0, _new_vehicle_id, found->index); InvalidateWindowClassesData(WC_TRAINS_LIST, 0); } } diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index ccec4705dc..005cebd467 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -230,7 +230,7 @@ public: TileIndex tile = TileVirtXY(pt.x, pt.y); if (this->mode == PM_NORMAL) { - DoCommandP(tile, this->tree_to_plant, tile, CMD_PLANT_TREE); + DoCommandP(CMD_PLANT_TREE, tile, this->tree_to_plant, tile); } else { this->DoPlantForest(tile); } @@ -240,7 +240,7 @@ public: void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL && pt.x != -1 && select_proc == DDSP_PLANT_TREES) { - DoCommandP(end_tile, this->tree_to_plant, start_tile, CMD_PLANT_TREE | CMD_MSG(STR_ERROR_CAN_T_PLANT_TREE_HERE)); + DoCommandP(CMD_PLANT_TREE | CMD_MSG(STR_ERROR_CAN_T_PLANT_TREE_HERE), end_tile, this->tree_to_plant, start_tile); } } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index e11e340f59..56e1bb713b 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1033,9 +1033,9 @@ struct RefitWindow : public Window { if (this->order == INVALID_VEH_ORDER_ID) { bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX; - if (DoCommandP(v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16, GetCmdRefitVeh(v)) && delete_window) this->Close(); + if (DoCommandP(GetCmdRefitVeh(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16) && delete_window) this->Close(); } else { - if (DoCommandP(v->tile, v->index, this->cargo->cargo | this->order << 16, CMD_ORDER_REFIT)) this->Close(); + if (DoCommandP(CMD_ORDER_REFIT, v->tile, v->index, this->cargo->cargo | this->order << 16)) this->Close(); } } break; @@ -1894,7 +1894,7 @@ public: case WID_VL_STOP_ALL: case WID_VL_START_ALL: - DoCommandP(0, (1 << 1) | (widget == WID_VL_START_ALL ? (1 << 0) : 0), this->window_number, CMD_MASS_START_STOP); + DoCommandP(CMD_MASS_START_STOP, 0, (1 << 1) | (widget == WID_VL_START_ALL ? (1 << 0) : 0), this->window_number); break; } } @@ -1919,7 +1919,7 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: // Send to Depots - DoCommandP(0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number, GetCmdSendToDepot(this->vli.vtype)); + DoCommandP(GetCmdSendToDepot(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number); break; default: NOT_REACHED(); @@ -2422,7 +2422,7 @@ struct VehicleDetailsWindow : Window { mod = GetServiceIntervalClamped(mod + v->GetServiceInterval(), v->ServiceIntervalIsPercent()); if (mod == v->GetServiceInterval()) return; - DoCommandP(v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17), CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SERVICING)); + DoCommandP(CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SERVICING), v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17)); break; } @@ -2458,7 +2458,7 @@ struct VehicleDetailsWindow : Window { bool iscustom = index != 0; bool ispercent = iscustom ? (index == 2) : Company::Get(v->owner)->settings.vehicle.servint_ispercent; uint16 interval = GetServiceIntervalClamped(v->GetServiceInterval(), ispercent); - DoCommandP(v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17), CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SERVICING)); + DoCommandP(CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SERVICING), v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17)); break; } } @@ -2639,7 +2639,7 @@ void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, ui void StartStopVehicle(const Vehicle *v, bool texteffect) { assert(v->IsPrimaryVehicle()); - DoCommandP(v->tile, v->index, 0, _vehicle_command_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr); + DoCommandP(_vehicle_command_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, 0); } /** Checks whether the vehicle may be refitted at the moment.*/ @@ -2963,7 +2963,7 @@ public: break; case WID_VV_GOTO_DEPOT: // goto hangar - DoCommandP(v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0, GetCmdSendToDepot(v)); + DoCommandP(GetCmdSendToDepot(v), v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0); break; case WID_VV_REFIT: // refit ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID, this); @@ -2987,18 +2987,17 @@ public: * There is no point to it except for starting the vehicle. * For starting the vehicle the player has to open the depot GUI, which is * most likely already open, but is also visible in the vehicle viewport. */ - DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, - _vehicle_command_translation_table[VCT_CMD_CLONE_VEH][v->type], - _ctrl_pressed ? nullptr : CcCloneVehicle); + DoCommandP(_vehicle_command_translation_table[VCT_CMD_CLONE_VEH][v->type], + _ctrl_pressed ? nullptr : CcCloneVehicle, + v->tile, v->index, _ctrl_pressed ? 1 : 0); break; case WID_VV_TURN_AROUND: // turn around assert(v->IsGroundVehicle()); - DoCommandP(v->tile, v->index, 0, - _vehicle_command_translation_table[VCT_CMD_TURN_AROUND][v->type]); + DoCommandP(_vehicle_command_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0); break; case WID_VV_FORCE_PROCEED: // force proceed assert(v->type == VEH_TRAIN); - DoCommandP(v->tile, v->index, 0, CMD_FORCE_TRAIN_PROCEED | CMD_MSG(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL)); + DoCommandP(CMD_FORCE_TRAIN_PROCEED | CMD_MSG(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL), v->tile, v->index, 0); break; } } @@ -3007,7 +3006,7 @@ public: { if (str == nullptr) return; - DoCommandP(0, this->window_number, 0, CMD_RENAME_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type), nullptr, str); + DoCommandP(CMD_RENAME_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type), 0, this->window_number, 0, str); } void OnMouseOver(Point pt, int widget) override diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp index 4dd2397b78..8a4772ac08 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.cpp @@ -138,7 +138,7 @@ public: { if (str == nullptr) return; - DoCommandP(0, this->window_number, 0, CMD_RENAME_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME), nullptr, str); + DoCommandP(CMD_RENAME_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME), 0, this->window_number, 0, str); } }; From a38bbefe1b28ac59b2a9fef45765fa3890cde32e Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 3 Oct 2021 21:13:32 +0200 Subject: [PATCH 05/60] Codechange: Untangle command code, flags and error string for DoCommand*. --- src/ai/ai_instance.cpp | 2 +- src/airport_gui.cpp | 4 +- src/autoreplace_cmd.cpp | 18 +++--- src/bridge_gui.cpp | 6 +- src/build_vehicle_gui.cpp | 6 +- src/command.cpp | 101 +++++++++++++++++++----------- src/command_func.h | 18 +++--- src/command_type.h | 29 ++------- src/company_gui.cpp | 18 +++--- src/depot_gui.cpp | 15 +++-- src/dock_gui.cpp | 18 +++--- src/economy.cpp | 4 +- src/game/game_instance.cpp | 2 +- src/group_gui.cpp | 24 +++---- src/industry_gui.cpp | 8 +-- src/main_gui.cpp | 2 +- src/network/network.cpp | 8 ++- src/network/network_admin.cpp | 6 +- src/network/network_client.cpp | 2 +- src/network/network_command.cpp | 16 ++--- src/network/network_gui.cpp | 2 +- src/network/network_server.cpp | 6 +- src/object_gui.cpp | 2 +- src/order_backup.cpp | 2 +- src/order_gui.cpp | 32 +++++----- src/rail_gui.cpp | 45 +++++++------ src/road_gui.cpp | 32 +++++----- src/script/api/script_object.cpp | 12 ++-- src/script/api/script_object.hpp | 7 ++- src/script/api/script_vehicle.cpp | 16 +++-- src/script/script_instance.cpp | 2 +- src/script/script_instance.hpp | 2 +- src/script/script_storage.hpp | 2 +- src/settings.cpp | 2 +- src/signs_cmd.cpp | 4 +- src/signs_gui.cpp | 2 +- src/station_gui.cpp | 2 +- src/terraform_gui.cpp | 14 ++--- src/timetable_gui.cpp | 12 ++-- src/town_gui.cpp | 14 ++--- src/train_gui.cpp | 2 +- src/tree_gui.cpp | 2 +- src/vehicle.cpp | 2 +- src/vehicle_cmd.cpp | 64 +++++++++---------- src/vehicle_func.h | 40 ++++++------ src/vehicle_gui.cpp | 56 +++++++++-------- src/waypoint_gui.cpp | 2 +- 47 files changed, 348 insertions(+), 339 deletions(-) diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index 9e1f001631..da79d7c132 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -98,7 +98,7 @@ ScriptInfo *AIInstance::FindLibrary(const char *library, int version) * @param p2 p2 as given to DoCommandPInternal. * @param cmd cmd as given to DoCommandPInternal. */ -void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { /* * The company might not exist anymore. Check for this. diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 4d09fbdfdf..a031c450c3 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -40,7 +40,7 @@ static void ShowBuildAirportPicker(Window *parent); SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout); -void CcBuildAirport(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcBuildAirport(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -60,7 +60,7 @@ static void PlaceAirport(TileIndex tile) uint32 p1 = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex(); p1 |= _selected_airport_layout << 8; - CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_AIRPORT | CMD_MSG(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE), CcBuildAirport, "" }; + CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_AIRPORT, STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, "" }; ShowSelectStationIfNeeded(cmdcont, TileArea(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE)); } diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 617c3bc6c1..2602d86ada 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -340,7 +340,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic } /* Build the new vehicle */ - cost = DoCommand(DC_EXEC | DC_AUTOREPLACE, GetCmdBuildVeh(old_veh), old_veh->tile, e | (CT_INVALID << 24), 0); + cost = DoCommand(DC_EXEC | DC_AUTOREPLACE, CMD_BUILD_VEHICLE, old_veh->tile, e | (CT_INVALID << 24), 0); if (cost.Failed()) return cost; Vehicle *new_veh = Vehicle::Get(_new_vehicle_id); @@ -350,7 +350,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic if (refit_cargo != CT_NO_REFIT) { byte subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo); - cost.AddCost(DoCommand(DC_EXEC, GetCmdRefitVeh(new_veh), 0, new_veh->index, refit_cargo | (subtype << 8))); + cost.AddCost(DoCommand(DC_EXEC, CMD_REFIT_VEHICLE, 0, new_veh->index, refit_cargo | (subtype << 8))); assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace() } @@ -466,11 +466,11 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b } /* Sell the old vehicle */ - cost.AddCost(DoCommand(flags, GetCmdSellVeh(old_v), 0, old_v->index, 0)); + cost.AddCost(DoCommand(flags, CMD_SELL_VEHICLE, 0, old_v->index, 0)); /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - DoCommand(DC_EXEC, GetCmdSellVeh(new_v), 0, new_v->index, 0); + DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, new_v->index, 0); } } @@ -597,7 +597,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON); /* Sell wagon */ - [[maybe_unused]] CommandCost ret = DoCommand(DC_EXEC, GetCmdSellVeh(wagon), 0, wagon->index, 0); + [[maybe_unused]] CommandCost ret = DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, wagon->index, 0); assert(ret.Succeeded()); new_vehs[i] = nullptr; @@ -629,7 +629,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Sell the vehicle. * Note: This might temporarily construct new trains, so use DC_AUTOREPLACE to prevent * it from failing due to engine limits. */ - cost.AddCost(DoCommand(flags | DC_AUTOREPLACE, GetCmdSellVeh(w), 0, w->index, 0)); + cost.AddCost(DoCommand(flags | DC_AUTOREPLACE, CMD_SELL_VEHICLE, 0, w->index, 0)); if ((flags & DC_EXEC) != 0) { old_vehs[i] = nullptr; if (i == 0) old_head = nullptr; @@ -660,7 +660,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon if ((flags & DC_EXEC) == 0) { for (int i = num_units - 1; i >= 0; i--) { if (new_vehs[i] != nullptr) { - DoCommand(DC_EXEC, GetCmdSellVeh(new_vehs[i]), 0, new_vehs[i]->index, 0); + DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, new_vehs[i]->index, 0); new_vehs[i] = nullptr; } } @@ -691,12 +691,12 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon } /* Sell the old vehicle */ - cost.AddCost(DoCommand(flags, GetCmdSellVeh(old_head), 0, old_head->index, 0)); + cost.AddCost(DoCommand(flags, CMD_SELL_VEHICLE, 0, old_head->index, 0)); } /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - DoCommand(DC_EXEC, GetCmdSellVeh(new_head), 0, new_head->index, 0); + DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, new_head->index, 0); } } } diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 2aef088e3f..d5347989ed 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -58,7 +58,7 @@ typedef GUIList GUIBridgeList; ///< List of bridges, used in #B * - p2 = (bit 15-16) - transport type. * @param cmd unused */ -void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uint32 p2, uint32 cmd) +void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile); @@ -117,7 +117,7 @@ private: case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->at(i).index; break; default: break; } - DoCommandP(CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge, + DoCommandP(CMD_BUILD_BRIDGE, STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, this->end_tile, this->start_tile, this->type | this->bridges->at(i).index); } @@ -383,7 +383,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo default: break; // water ways and air routes don't have bridge types } if (_ctrl_pressed && CheckBridgeAvailability(last_bridge_type, bridge_len).Succeeded()) { - DoCommandP(CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge, end, start, type | last_bridge_type); + DoCommandP(CMD_BUILD_BRIDGE, STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, type | last_bridge_type); return; } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index aafc0a950e..b1136ec302 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1226,7 +1226,7 @@ struct BuildVehicleWindow : Window { if (!this->listview_mode) { /* Query for cost and refitted capacity */ - CommandCost ret = DoCommand(DC_QUERY_COST, GetCmdBuildVeh(this->vehicle_type), this->window_number, this->sel_engine | (cargo << 24), 0); + CommandCost ret = DoCommand(DC_QUERY_COST, CMD_BUILD_VEHICLE, this->window_number, this->sel_engine | (cargo << 24), 0); if (ret.Succeeded()) { this->te.cost = ret.GetCost() - e->GetCost(); this->te.capacity = _returned_refit_capacity; @@ -1469,7 +1469,7 @@ struct BuildVehicleWindow : Window { CommandCallback *callback = (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildPrimaryVehicle; CargoID cargo = this->cargo_filter[this->cargo_filter_criteria]; if (cargo == CF_ANY || cargo == CF_ENGINES) cargo = CF_NONE; - DoCommandP(GetCmdBuildVeh(this->vehicle_type), callback, this->window_number, sel_eng | (cargo << 24), 0); + DoCommandP(CMD_BUILD_VEHICLE, GetCmdBuildVehMsg(this->vehicle_type), callback, this->window_number, sel_eng | (cargo << 24), 0); } break; } @@ -1634,7 +1634,7 @@ struct BuildVehicleWindow : Window { { if (str == nullptr) return; - DoCommandP(CMD_RENAME_ENGINE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type), 0, this->rename_engine, 0, str); + DoCommandP(CMD_RENAME_ENGINE, STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, 0, this->rename_engine, 0, str); } void OnDropdownSelect(int widget, int index) override diff --git a/src/command.cpp b/src/command.cpp index d397d3fe6a..449fdece28 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -378,8 +378,6 @@ static const Command _command_proc_table[] = { */ bool IsValidCommand(uint32 cmd) { - cmd &= CMD_ID_MASK; - return cmd < lengthof(_command_proc_table) && _command_proc_table[cmd].proc != nullptr; } @@ -390,11 +388,11 @@ bool IsValidCommand(uint32 cmd) * @param cmd The integer value of the command * @return The flags for this command */ -CommandFlags GetCommandFlags(uint32 cmd) +CommandFlags GetCommandFlags(Commands cmd) { assert(IsValidCommand(cmd)); - return _command_proc_table[cmd & CMD_ID_MASK].flags; + return _command_proc_table[cmd].flags; } /*! @@ -404,11 +402,11 @@ CommandFlags GetCommandFlags(uint32 cmd) * @param cmd The integer value of the command * @return The name for this command */ -const char *GetCommandName(uint32 cmd) +const char *GetCommandName(Commands cmd) { assert(IsValidCommand(cmd)); - return _command_proc_table[cmd & CMD_ID_MASK].name; + return _command_proc_table[cmd].name; } /** @@ -433,7 +431,7 @@ bool IsCommandAllowedWhilePaused(uint32 cmd) static_assert(lengthof(command_type_lookup) == CMDT_END); assert(IsValidCommand(cmd)); - return _game_mode == GM_EDITOR || command_type_lookup[_command_proc_table[cmd & CMD_ID_MASK].type] <= _settings_game.construction.command_pause_level; + return _game_mode == GM_EDITOR || command_type_lookup[_command_proc_table[cmd].type] <= _settings_game.construction.command_pause_level; } @@ -449,7 +447,7 @@ static int _docommand_recursive = 0; */ CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags) { - return DoCommand(flags, container->cmd & CMD_ID_MASK, container->tile, container->p1, container->p2, container->text); + return DoCommand(flags, container->cmd, container->tile, container->p1, container->p2, container->text); } /*! @@ -465,7 +463,7 @@ CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags) * @see CommandProc * @return the cost */ -CommandCost DoCommand(DoCommandFlag flags, uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CommandCost res; @@ -473,7 +471,7 @@ CommandCost DoCommand(DoCommandFlag flags, uint32 cmd, TileIndex tile, uint32 p1 if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return CMD_ERROR; /* Chop of any CMD_MSG or other flags; we don't need those here */ - CommandProc *proc = _command_proc_table[cmd & CMD_ID_MASK].proc; + CommandProc *proc = _command_proc_table[cmd].proc; _docommand_recursive++; @@ -542,13 +540,14 @@ Money GetAvailableMoneyForCommand() * @param cmd The command to execute (a CMD_* value) * @param callback A callback function to call after the command is finished * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) + * @param network_command execute the command without sending it on the network * @param tile The tile to perform a command on (see #CommandProc) * @param p1 Additional data for the command (see #CommandProc) * @param p2 Additional data for the command (see #CommandProc) * @param text The text to pass * @return \c true if the command succeeded, else \c false. */ -static bool DoCommandP(uint32 cmd, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +static bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* Cost estimation is generally only done when the * local user presses shift while doing something. @@ -557,31 +556,30 @@ static bool DoCommandP(uint32 cmd, CommandCallback *callback, bool my_cmd, TileI * to execute. */ bool estimate_only = _shift_pressed && IsLocalCompany() && !_generating_world && - !(cmd & CMD_NETWORK_COMMAND) && + !network_command && !(GetCommandFlags(cmd) & CMD_NO_EST); /* We're only sending the command, so don't do * fancy things for 'success'. */ - bool only_sending = _networking && !(cmd & CMD_NETWORK_COMMAND); + bool only_sending = _networking && !network_command; /* Where to show the message? */ int x = TileX(tile) * TILE_SIZE; int y = TileY(tile) * TILE_SIZE; if (_pause_mode != PM_UNPAUSED && !IsCommandAllowedWhilePaused(cmd) && !estimate_only) { - ShowErrorMessage(GB(cmd, 16, 16), STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, x, y); + ShowErrorMessage(err_message, STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, x, y); return false; } /* Only set p2 when the command does not come from the network. */ - if (!(cmd & CMD_NETWORK_COMMAND) && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER; + if (!network_command && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER; - CommandCost res = DoCommandPInternal(cmd, callback, my_cmd, estimate_only, tile, p1, p2, text); + CommandCost res = DoCommandPInternal(cmd, err_message, callback, my_cmd, estimate_only, network_command, tile, p1, p2, text); if (res.Failed()) { /* Only show the error when it's for us. */ - StringID error_part1 = GB(cmd, 16, 16); - if (estimate_only || (IsLocalCompany() && error_part1 != 0 && my_cmd)) { - ShowErrorMessage(error_part1, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackGRF(), res.GetTextRefStackSize(), res.GetTextRefStack()); + if (estimate_only || (IsLocalCompany() && err_message != 0 && my_cmd)) { + ShowErrorMessage(err_message, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackGRF(), res.GetTextRefStackSize(), res.GetTextRefStack()); } } else if (estimate_only) { ShowEstimatedCostOrIncome(res.GetCost(), x, y); @@ -605,25 +603,56 @@ static bool DoCommandP(uint32 cmd, CommandCallback *callback, bool my_cmd, TileI * Shortcut for the long DoCommandP when having a container with the data. * @param container the container with information. * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) + * @param network_command execute the command without sending it on the network * @return true if the command succeeded, else false */ -bool DoCommandP(const CommandContainer *container, bool my_cmd) +bool DoCommandP(const CommandContainer *container, bool my_cmd, bool network_command) { - return DoCommandP(container->cmd, container->callback, my_cmd, container->tile, container->p1, container->p2, container->text); + return DoCommandP(container->cmd, container->err_msg, container->callback, my_cmd, network_command, container->tile, container->p1, container->p2, container->text); +} + +/** + * Shortcut for the long DoCommandP when not using a callback or error message. + * @param cmd The command to execute (a CMD_* value) + * @param tile The tile to perform a command on (see #CommandProc) + * @param p1 Additional data for the command (see #CommandProc) + * @param p2 Additional data for the command (see #CommandProc) + * @param text The text to pass + * @return \c true if the command succeeded, else \c false. + */ +bool DoCommandP(Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +{ + return DoCommandP(cmd, STR_NULL, nullptr, true, false, tile, p1, p2, text); +} + +/** + * Shortcut for the long DoCommandP when not using an error message. + * @param cmd The command to execute (a CMD_* value) + * @param callback A callback function to call after the command is finished + * @param tile The tile to perform a command on (see #CommandProc) + * @param p1 Additional data for the command (see #CommandProc) + * @param p2 Additional data for the command (see #CommandProc) + * @param text The text to pass + * @return \c true if the command succeeded, else \c false. + */ +bool DoCommandP(Commands cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +{ + return DoCommandP(cmd, STR_NULL, callback, true, false, tile, p1, p2, text); } /** * Shortcut for the long DoCommandP when not using a callback. * @param cmd The command to execute (a CMD_* value) + * @param err_message Message prefix to show on error * @param tile The tile to perform a command on (see #CommandProc) * @param p1 Additional data for the command (see #CommandProc) * @param p2 Additional data for the command (see #CommandProc) * @param text The text to pass * @return \c true if the command succeeded, else \c false. */ -bool DoCommandP(uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +bool DoCommandP(Commands cmd, StringID err_message, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { - return DoCommandP(cmd, nullptr, true, tile, p1, p2, text); + return DoCommandP(cmd, err_message, nullptr, true, false, tile, p1, p2, text); } /*! @@ -632,6 +661,7 @@ bool DoCommandP(uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::str * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. * * @param cmd The command to execute (a CMD_* value) + * @param err_message Message prefix to show on error * @param callback A callback function to call after the command is finished * @param tile The tile to perform a command on (see #CommandProc) * @param p1 Additional data for the command (see #CommandProc) @@ -639,9 +669,9 @@ bool DoCommandP(uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::str * @param text The text to pass * @return \c true if the command succeeded, else \c false. */ -bool DoCommandP(uint32 cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { - return DoCommandP(cmd, callback, true, tile, p1, p2, text); + return DoCommandP(cmd, err_message, callback, true, false, tile, p1, p2, text); } /** @@ -654,6 +684,7 @@ bool DoCommandP(uint32 cmd, CommandCallback *callback, TileIndex tile, uint32 p1 * Helper function for the toplevel network safe docommand function for the current company. * * @param cmd The command to execute (a CMD_* value) + * @param err_message Message prefix to show on error * @param callback A callback function to call after the command is finished * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) * @param estimate_only whether to give only the estimate or also execute the command @@ -663,7 +694,7 @@ bool DoCommandP(uint32 cmd, CommandCallback *callback, TileIndex tile, uint32 p1 * @param text The text to pass * @return the command cost of this function. */ -CommandCost DoCommandPInternal(uint32 cmd, CommandCallback *callback, bool my_cmd, bool estimate_only, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* Prevent recursion; it gives a mess over the network */ assert(_docommand_recursive == 0); @@ -673,10 +704,8 @@ CommandCost DoCommandPInternal(uint32 cmd, CommandCallback *callback, bool my_cm _additional_cash_required = 0; /* Get pointer to command handler */ - byte cmd_id = cmd & CMD_ID_MASK; - assert(cmd_id < lengthof(_command_proc_table)); - - CommandProc *proc = _command_proc_table[cmd_id].proc; + assert(cmd < lengthof(_command_proc_table)); + CommandProc *proc = _command_proc_table[cmd].proc; /* Shouldn't happen, but you never know when someone adds * NULLs to the _command_proc_table. */ assert(proc != nullptr); @@ -725,10 +754,10 @@ CommandCost DoCommandPInternal(uint32 cmd, CommandCallback *callback, bool my_cm * we bail out here. */ if (res.Failed() || estimate_only || (!test_and_exec_can_differ && !CheckCompanyHasMoney(res))) { - if (!_networking || _generating_world || (cmd & CMD_NETWORK_COMMAND) != 0) { + if (!_networking || _generating_world || network_command) { /* Log the failed command as well. Just to be able to be find * causes of desyncs due to bad command test implementations. */ - Debug(desync, 1, "cmdf: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd)); + Debug(desync, 1, "cmdf: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd, err_message, text, GetCommandName(cmd)); } cur_company.Restore(); return_dcpi(res); @@ -738,8 +767,8 @@ CommandCost DoCommandPInternal(uint32 cmd, CommandCallback *callback, bool my_cm * If we are in network, and the command is not from the network * send it to the command-queue and abort execution */ - if (_networking && !_generating_world && !(cmd & CMD_NETWORK_COMMAND)) { - NetworkSendCommand(cmd & ~CMD_FLAGS_MASK, callback, _current_company, tile, p1, p2, text); + if (_networking && !_generating_world && !network_command) { + NetworkSendCommand(cmd, err_message, callback, _current_company, tile, p1, p2, text); cur_company.Restore(); /* Don't return anything special here; no error, no costs. @@ -748,7 +777,7 @@ CommandCost DoCommandPInternal(uint32 cmd, CommandCallback *callback, bool my_cm * reset the storages as we've not executed the command. */ return_dcpi(CommandCost()); } - Debug(desync, 1, "cmd: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd)); + Debug(desync, 1, "cmd: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd, err_message, text, GetCommandName(cmd)); /* Actually try and execute the command. If no cost-type is given * use the construction one */ @@ -757,7 +786,7 @@ CommandCost DoCommandPInternal(uint32 cmd, CommandCallback *callback, bool my_cm CommandCost res2 = proc(tile, flags | DC_EXEC, p1, p2, text); BasePersistentStorageArray::SwitchMode(PSM_LEAVE_COMMAND); - if (cmd_id == CMD_COMPANY_CTRL) { + if (cmd == CMD_COMPANY_CTRL) { cur_company.Trash(); /* We are a new company -> Switch to new local company. * We were closed down -> Switch to spectator diff --git a/src/command_func.h b/src/command_func.h index eefaadd9b6..662ae00a5c 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -32,22 +32,24 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); */ #define return_cmd_error(errcode) return CommandCost(errcode); -CommandCost DoCommand(DoCommandFlag flags, uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); +CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags); -bool DoCommandP(uint32 cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -bool DoCommandP(uint32 cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -bool DoCommandP(const CommandContainer *container, bool my_cmd = true); +bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); +bool DoCommandP(Commands cmd, StringID err_message, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); +bool DoCommandP(Commands cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); +bool DoCommandP(Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); +bool DoCommandP(const CommandContainer *container, bool my_cmd = true, bool network_command = false); -CommandCost DoCommandPInternal(uint32 cmd, CommandCallback *callback, bool my_cmd, bool estimate_only, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); +CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); -void NetworkSendCommand(uint32 cmd, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); +void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); extern Money _additional_cash_required; bool IsValidCommand(uint32 cmd); -CommandFlags GetCommandFlags(uint32 cmd); -const char *GetCommandName(uint32 cmd); +CommandFlags GetCommandFlags(Commands cmd); +const char *GetCommandName(Commands cmd); Money GetAvailableMoneyForCommand(); bool IsCommandAllowedWhilePaused(uint32 cmd); diff --git a/src/command_type.h b/src/command_type.h index 61154ea04b..972db596ea 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -172,7 +172,7 @@ public: * * @see _command_proc_table */ -enum Commands { +enum Commands : uint16 { CMD_BUILD_RAILROAD_TRACK, ///< build a rail track CMD_REMOVE_RAILROAD_TRACK, ///< remove a rail track CMD_BUILD_SINGLE_RAIL, ///< build a single rail track @@ -360,28 +360,6 @@ enum DoCommandFlag { }; DECLARE_ENUM_AS_BIT_SET(DoCommandFlag) -/** - * Used to combine a StringID with the command. - * - * This macro can be used to add a StringID (the error message to show) on a command-id - * (CMD_xxx). Use the binary or-operator "|" to combine the command with the result from - * this macro. - * - * @param x The StringID to combine with a command-id - */ -#define CMD_MSG(x) ((x) << 16) - -/** - * Defines some flags. - * - * This enumeration defines some flags which are binary-or'ed on a command. - */ -enum FlaggedCommands { - CMD_NETWORK_COMMAND = 0x0100, ///< execute the command without sending it on the network - CMD_FLAGS_MASK = 0xFF00, ///< mask for all command flags - CMD_ID_MASK = 0x00FF, ///< mask for the command ID -}; - /** * Command flags for the command table _command_proc_table. * @@ -471,7 +449,7 @@ struct Command { * @param p1 Additional data of the command * @see CommandProc */ -typedef void CommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd); +typedef void CommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd); /** * Structure for buffering the build command when selecting a station to join. @@ -480,7 +458,8 @@ struct CommandContainer { TileIndex tile; ///< tile command being executed on. uint32 p1; ///< parameter p1. uint32 p2; ///< parameter p2. - uint32 cmd; ///< command being executed. + Commands cmd; ///< command being executed. + StringID err_msg; ///< string ID of error message to use. CommandCallback *callback; ///< any callback function executed upon successful completion of the command. std::string text; ///< possible text sent for name changes etc. }; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index d8b468ad91..6ab3b0aa7d 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -435,11 +435,11 @@ struct CompanyFinancesWindow : Window { break; case WID_CF_INCREASE_LOAN: // increase loan - DoCommandP(CMD_INCREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY), 0, 0, _ctrl_pressed); + DoCommandP(CMD_INCREASE_LOAN, STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY, 0, 0, _ctrl_pressed); break; case WID_CF_REPAY_LOAN: // repay loan - DoCommandP(CMD_DECREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_REPAY_LOAN), 0, 0, _ctrl_pressed); + DoCommandP(CMD_DECREASE_LOAN, STR_ERROR_CAN_T_REPAY_LOAN, 0, 0, _ctrl_pressed); break; case WID_CF_INFRASTRUCTURE: // show infrastructure details @@ -2576,11 +2576,11 @@ struct CompanyWindow : Window break; case WID_C_BUY_SHARE: - DoCommandP(CMD_BUY_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS), 0, this->window_number, 0); + DoCommandP(CMD_BUY_SHARE_IN_COMPANY, STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, 0, this->window_number, 0); break; case WID_C_SELL_SHARE: - DoCommandP(CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_SELL_25_SHARE_IN), 0, this->window_number, 0); + DoCommandP(CMD_SELL_SHARE_IN_COMPANY, STR_ERROR_CAN_T_SELL_25_SHARE_IN, 0, this->window_number, 0); break; case WID_C_COMPANY_PASSWORD: @@ -2613,7 +2613,7 @@ struct CompanyWindow : Window void OnPlaceObject(Point pt, TileIndex tile) override { - if (DoCommandP(CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS), tile, OBJECT_HQ, 0) && !_shift_pressed) { + if (DoCommandP(CMD_BUILD_OBJECT, STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS, tile, OBJECT_HQ, 0) && !_shift_pressed) { ResetObjectToPlace(); this->RaiseButtons(); } @@ -2635,16 +2635,16 @@ struct CompanyWindow : Window Money money = (Money)(strtoull(str, nullptr, 10) / _currency->rate); uint32 money_c = Clamp(ClampToI32(money), 0, 20000000); // Clamp between 20 million and 0 - DoCommandP(CMD_GIVE_MONEY | CMD_MSG(STR_ERROR_CAN_T_GIVE_MONEY), 0, money_c, this->window_number); + DoCommandP(CMD_GIVE_MONEY, STR_ERROR_CAN_T_GIVE_MONEY, 0, money_c, this->window_number); break; } case WID_C_PRESIDENT_NAME: - DoCommandP(CMD_RENAME_PRESIDENT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_PRESIDENT), 0, 0, 0, str); + DoCommandP(CMD_RENAME_PRESIDENT, STR_ERROR_CAN_T_CHANGE_PRESIDENT, 0, 0, 0, str); break; case WID_C_COMPANY_NAME: - DoCommandP(CMD_RENAME_COMPANY | CMD_MSG(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME), 0, 0, 0, str); + DoCommandP(CMD_RENAME_COMPANY, STR_ERROR_CAN_T_CHANGE_COMPANY_NAME, 0, 0, 0, str); break; case WID_C_COMPANY_JOIN: @@ -2771,7 +2771,7 @@ struct BuyCompanyWindow : Window { break; case WID_BC_YES: - DoCommandP(CMD_BUY_COMPANY | CMD_MSG(STR_ERROR_CAN_T_BUY_COMPANY), 0, this->window_number, 0); + DoCommandP(CMD_BUY_COMPANY, STR_ERROR_CAN_T_BUY_COMPANY, 0, this->window_number, 0); break; } } diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 7ff812c230..8515258f0f 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -117,7 +117,7 @@ extern void DepotSortList(VehicleList *list); * @param p2 unused * @param cmd unused */ -void CcCloneVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcCloneVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -141,7 +141,7 @@ static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Veh if (wagon == v) return; - DoCommandP(CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE), v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index); + DoCommandP(CMD_MOVE_RAIL_VEHICLE, STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index); } static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END]; ///< Cell size for vehicle images in the depot view. @@ -836,7 +836,7 @@ struct DepotWindow : Window { if (str == nullptr) return; /* Do depot renaming */ - DoCommandP(CMD_RENAME_DEPOT | CMD_MSG(STR_ERROR_CAN_T_RENAME_DEPOT), 0, this->GetDepotIndex(), 0, str); + DoCommandP(CMD_RENAME_DEPOT, STR_ERROR_CAN_T_RENAME_DEPOT, 0, this->GetDepotIndex(), 0, str); } bool OnRightClick(Point pt, int widget) override @@ -904,10 +904,10 @@ struct DepotWindow : Window { { if (_ctrl_pressed) { /* Share-clone, do not open new viewport, and keep tool active */ - DoCommandP(CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), this->window_number, v->index, 1); + DoCommandP(CMD_CLONE_VEHICLE, STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, 1); } else { /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to changs things on new vehicle) */ - if (DoCommandP(CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), CcCloneVehicle, this->window_number, v->index, 0)) { + if (DoCommandP(CMD_CLONE_VEHICLE, STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, 0)) { ResetObjectToPlace(); } } @@ -1001,8 +1001,7 @@ struct DepotWindow : Window { if (this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, &gdvp) == MODE_DRAG_VEHICLE && sel != INVALID_VEHICLE) { if (gdvp.wagon != nullptr && gdvp.wagon->index == sel && _ctrl_pressed) { - DoCommandP(CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE), - Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true); + DoCommandP(CMD_REVERSE_TRAIN_DIRECTION, STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true); } else if (gdvp.wagon == nullptr || gdvp.wagon->index != sel) { this->vehicle_over = INVALID_VEHICLE; TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head); @@ -1027,7 +1026,7 @@ struct DepotWindow : Window { this->SetDirty(); int sell_cmd = (v->type == VEH_TRAIN && (widget == WID_D_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0; - DoCommandP(GetCmdSellVeh(v->type), v->tile, v->index | sell_cmd << 20 | MAKE_ORDER_BACKUP_FLAG, 0); + DoCommandP(CMD_SELL_VEHICLE, GetCmdSellVehMsg(v->type), v->tile, v->index | sell_cmd << 20 | MAKE_ORDER_BACKUP_FLAG, 0); break; } diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 0911555a4e..c1f6156122 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -38,7 +38,7 @@ static void ShowBuildDocksDepotPicker(Window *parent); static Axis _ship_depot_direction; -void CcBuildDocks(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcBuildDocks(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -46,7 +46,7 @@ void CcBuildDocks(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } -void CcPlaySound_CONSTRUCTION_WATER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcPlaySound_CONSTRUCTION_WATER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_02_CONSTRUCTION_WATER, tile); } @@ -191,7 +191,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_LOCK: // Build lock button - DoCommandP(CMD_BUILD_LOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_LOCKS), CcBuildDocks, tile, 0, 0); + DoCommandP(CMD_BUILD_LOCK, STR_ERROR_CAN_T_BUILD_LOCKS, CcBuildDocks, tile, 0, 0); break; case WID_DT_DEMOLISH: // Demolish aka dynamite button @@ -199,14 +199,14 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_DEPOT: // Build depot button - DoCommandP(CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks, tile, _ship_depot_direction, 0); + DoCommandP(CMD_BUILD_SHIP_DEPOT, STR_ERROR_CAN_T_BUILD_SHIP_DEPOT, CcBuildDocks, tile, _ship_depot_direction, 0); break; case WID_DT_STATION: { // Build station button uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join /* tile is always the land tile, so need to evaluate _thd.pos */ - CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" }; + CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK, STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, "" }; /* Determine the watery part of the dock. */ DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); @@ -217,7 +217,7 @@ struct BuildDocksToolbarWindow : Window { } case WID_DT_BUOY: // Build buoy button - DoCommandP(CMD_BUILD_BUOY | CMD_MSG(STR_ERROR_CAN_T_POSITION_BUOY_HERE), CcBuildDocks, tile, 0, 0); + DoCommandP(CMD_BUILD_BUOY, STR_ERROR_CAN_T_POSITION_BUOY_HERE, CcBuildDocks, tile, 0, 0); break; case WID_DT_RIVER: // Build river button (in scenario editor) @@ -225,7 +225,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button - DoCommandP(CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE), CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15); + DoCommandP(CMD_BUILD_BRIDGE, STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15); break; default: NOT_REACHED(); @@ -245,10 +245,10 @@ struct BuildDocksToolbarWindow : Window { GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; case DDSP_CREATE_WATER: - DoCommandP(CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_BUILD_CANALS), CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL); + DoCommandP(CMD_BUILD_CANAL, STR_ERROR_CAN_T_BUILD_CANALS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL); break; case DDSP_CREATE_RIVER: - DoCommandP(CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_PLACE_RIVERS), CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0)); + DoCommandP(CMD_BUILD_CANAL, STR_ERROR_CAN_T_PLACE_RIVERS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0)); break; default: break; diff --git a/src/economy.cpp b/src/economy.cpp index b7100257a0..3beeb25f58 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1485,7 +1485,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station if (st->goods[cid].cargo.HasCargoFor(next_station)) { /* Try to find out if auto-refitting would succeed. In case the refit is allowed, * the returned refit capacity will be greater than zero. */ - DoCommand(DC_QUERY_COST, GetCmdRefitVeh(v_start), v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16); // Auto-refit and only this vehicle including artic parts. + DoCommand(DC_QUERY_COST, CMD_REFIT_VEHICLE, v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16); // Auto-refit and only this vehicle including artic parts. /* Try to balance different loadable cargoes between parts of the consist, so that * all of them can be loaded. Avoid a situation where all vehicles suddenly switch * to the first loadable cargo for which there is only one packet. If the capacities @@ -1508,7 +1508,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station * "via any station" before reserving. We rather produce some more "any station" cargo than * misrouting it. */ IterateVehicleParts(v_start, ReturnCargoAction(st, INVALID_STATION)); - CommandCost cost = DoCommand(DC_EXEC, GetCmdRefitVeh(v_start), v_start->tile, v_start->index, new_cid | 1U << 24 | 0xFF << 8 | 1U << 16); // Auto-refit and only this vehicle including artic parts. + CommandCost cost = DoCommand(DC_EXEC, CMD_REFIT_VEHICLE, v_start->tile, v_start->index, new_cid | 1U << 24 | 0xFF << 8 | 1U << 16); // Auto-refit and only this vehicle including artic parts. if (cost.Succeeded()) v->First()->profit_this_year -= cost.GetCost() << 8; } diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp index 842b4b3e47..abd0541159 100644 --- a/src/game/game_instance.cpp +++ b/src/game/game_instance.cpp @@ -87,7 +87,7 @@ void GameInstance::Died() * @param p2 p2 as given to DoCommandPInternal. * @param cmd cmd as given to DoCommandPInternal. */ -void CcGame(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcGame(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (Game::GetGameInstance()->DoCommandCallback(result, tile, p1, p2, cmd)) { Game::GetGameInstance()->Continue(); diff --git a/src/group_gui.cpp b/src/group_gui.cpp index ee8e604744..316cdc4f3c 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -640,7 +640,7 @@ public: if (confirmed) { VehicleGroupWindow *w = (VehicleGroupWindow*)win; w->vli.index = ALL_GROUP; - DoCommandP(CMD_DELETE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_DELETE), 0, w->group_confirm, 0); + DoCommandP(CMD_DELETE_GROUP, STR_ERROR_GROUP_CAN_T_DELETE, 0, w->group_confirm, 0); } } @@ -771,7 +771,7 @@ public: } case WID_GL_CREATE_GROUP: { // Create a new group - DoCommandP(CMD_CREATE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_CREATE), CcCreateGroup, 0, this->vli.vtype, this->vli.index); + DoCommandP(CMD_CREATE_GROUP, STR_ERROR_GROUP_CAN_T_CREATE, CcCreateGroup, 0, this->vli.vtype, this->vli.index); break; } @@ -822,7 +822,7 @@ public: case WID_GL_ALL_VEHICLES: // All vehicles case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles if (g->parent != INVALID_GROUP) { - DoCommandP(CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT), 0, this->group_sel | (1 << 16), INVALID_GROUP); + DoCommandP(CMD_ALTER_GROUP, STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), INVALID_GROUP); } this->group_sel = INVALID_GROUP; @@ -835,7 +835,7 @@ public: GroupID new_g = id_g >= this->groups.size() ? INVALID_GROUP : this->groups[id_g]->index; if (this->group_sel != new_g && g->parent != new_g) { - DoCommandP(CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT), 0, this->group_sel | (1 << 16), new_g); + DoCommandP(CMD_ALTER_GROUP, STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), new_g); } this->group_sel = INVALID_GROUP; @@ -850,7 +850,7 @@ public: { switch (widget) { case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles - DoCommandP(CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE), 0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); + DoCommandP(CMD_ADD_VEHICLE_GROUP, STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, 0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); this->vehicle_sel = INVALID_VEHICLE; this->group_over = INVALID_GROUP; @@ -867,7 +867,7 @@ public: uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP); GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; - DoCommandP(CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE), new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); + DoCommandP(CMD_ADD_VEHICLE_GROUP, STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); break; } @@ -922,7 +922,7 @@ public: void OnQueryTextFinished(char *str) override { - if (str != nullptr) DoCommandP(CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), 0, this->group_rename, 0, str); + if (str != nullptr) DoCommandP(CMD_ALTER_GROUP, STR_ERROR_GROUP_CAN_T_RENAME, 0, this->group_rename, 0, str); this->group_rename = INVALID_GROUP; } @@ -952,19 +952,19 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: { // Send to Depots - DoCommandP(GetCmdSendToDepot(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack()); + DoCommandP(CMD_SEND_VEHICLE_TO_DEPOT, GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack()); break; } case ADI_ADD_SHARED: // Add shared Vehicles assert(Group::IsValidID(this->vli.index)); - DoCommandP(CMD_ADD_SHARED_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE), 0, this->vli.index, this->vli.vtype); + DoCommandP(CMD_ADD_SHARED_VEHICLE_GROUP, STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE, 0, this->vli.index, this->vli.vtype); break; case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group assert(Group::IsValidID(this->vli.index)); - DoCommandP(CMD_REMOVE_ALL_VEHICLES_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES), 0, this->vli.index, 0); + DoCommandP(CMD_REMOVE_ALL_VEHICLES_GROUP, STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, 0, this->vli.index, 0); break; default: NOT_REACHED(); } @@ -1146,7 +1146,7 @@ static inline VehicleGroupWindow *FindVehicleGroupWindow(VehicleType vt, Owner o * @param cmd Unused. * @see CmdCreateGroup */ -void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; assert(p1 <= VEH_AIRCRAFT); @@ -1163,7 +1163,7 @@ void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 * @param p2 Bit 0-19: Vehicle ID. * @param cmd Unused. */ -void CcAddVehicleNewGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcAddVehicleNewGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; assert(Vehicle::IsValidID(GB(p2, 0, 20))); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index e78b6853d3..cfdd2c6ca3 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -224,7 +224,7 @@ void SortIndustryTypes() * @param p2 Additional data of the #CMD_BUILD_INDUSTRY command. * @param cmd Unused. */ -void CcBuildIndustry(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcBuildIndustry(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Succeeded()) return; @@ -678,7 +678,7 @@ public: case WID_DPI_FUND_WIDGET: { if (this->selected_type != INVALID_INDUSTRYTYPE) { if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && GetIndustrySpec(this->selected_type)->IsRawIndustry()) { - DoCommandP(CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), 0, this->selected_type, InteractiveRandom()); + DoCommandP(CMD_BUILD_INDUSTRY, STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, 0, this->selected_type, InteractiveRandom()); this->HandleButtonClick(WID_DPI_FUND_WIDGET); } else { HandlePlacePushButton(this, WID_DPI_FUND_WIDGET, SPR_CURSOR_INDUSTRY, HT_RECT); @@ -715,13 +715,13 @@ public: Backup old_generating_world(_generating_world, true, FILE_LINE); _ignore_restrictions = true; - DoCommandP(CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry, tile, (layout_index << 8) | this->selected_type, seed); + DoCommandP(CMD_BUILD_INDUSTRY, STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, &CcBuildIndustry, tile, (layout_index << 8) | this->selected_type, seed); cur_company.Restore(); old_generating_world.Restore(); _ignore_restrictions = false; } else { - success = DoCommandP(CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), tile, (layout_index << 8) | this->selected_type, seed); + success = DoCommandP(CMD_BUILD_INDUSTRY, STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, (layout_index << 8) | this->selected_type, seed); } /* If an industry has been built, just reset the cursor and the system */ diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 46fff1a51b..d521f79d1a 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -76,7 +76,7 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl } -void CcPlaySound_EXPLOSION(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcPlaySound_EXPLOSION(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_12_EXPLOSION, tile); } diff --git a/src/network/network.cpp b/src/network/network.cpp index 6e111926ed..13f2fe52a4 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -1064,7 +1064,7 @@ void NetworkGameLoop() while (f != nullptr && !feof(f)) { if (_date == next_date && _date_fract == next_date_fract) { if (cp != nullptr) { - NetworkSendCommand(cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->company, cp->tile, cp->p1, cp->p2, cp->text); + NetworkSendCommand(cp->cmd, cp->err_msg, nullptr, cp->company, cp->tile, cp->p1, cp->p2, cp->text); Debug(desync, 0, "Injecting: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text, GetCommandName(cp->cmd)); delete cp; cp = nullptr; @@ -1103,14 +1103,16 @@ void NetworkGameLoop() if (*p == ' ') p++; cp = new CommandPacket(); int company; + uint cmd; char buffer[128]; - int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %x; \"%127[^\"]\"", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cp->cmd, buffer); + int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %x; %x; \"%127[^\"]\"", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cmd, &cp->err_msg, buffer); cp->text = buffer; /* There are 8 pieces of data to read, however the last is a * string that might or might not exist. Ignore it if that * string misses because in 99% of the time it's not used. */ - assert(ret == 8 || ret == 7); + assert(ret == 9 || ret == 8); cp->company = (CompanyID)company; + cp->cmd = (Commands)cmd; } else if (strncmp(p, "join: ", 6) == 0) { /* Manually insert a pause when joining; this way the client can join at the exact right time. */ int ret = sscanf(p + 6, "%x; %x", &next_date, &next_date_fract); diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 49b222f36f..99f803e24e 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -593,8 +593,8 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames() { Packet *p = new Packet(ADMIN_PACKET_SERVER_CMD_NAMES); - for (uint i = 0; i < CMD_END; i++) { - const char *cmdname = GetCommandName(i); + for (uint16 i = 0; i < CMD_END; i++) { + const char *cmdname = GetCommandName(static_cast(i)); /* Should COMPAT_MTU be exceeded, start a new packet * (magic 5: 1 bool "more data" and one uint16 "command id", one @@ -629,7 +629,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdLogging(ClientID clien p->Send_uint32(client_id); p->Send_uint8 (cp->company); - p->Send_uint16(cp->cmd & CMD_ID_MASK); + p->Send_uint16(cp->cmd); p->Send_uint32(cp->p1); p->Send_uint32(cp->p2); p->Send_uint32(cp->tile); diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index e638df0053..dd42f5f6ff 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -839,7 +839,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet * the server will give us a client-id and let us in */ _network_join_status = NETWORK_JOIN_STATUS_REGISTERING; ShowJoinStatusWindow(); - NetworkSendCommand(CMD_COMPANY_CTRL, nullptr, _local_company, 0, CCA_NEW, 0, {}); + NetworkSendCommand(CMD_COMPANY_CTRL, STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); } } else { /* take control over an existing company */ diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index f1a0f682d3..6df53d7da1 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -126,6 +126,7 @@ static CommandQueue _local_execution_queue; /** * Prepare a DoCommand to be send over the network * @param cmd The command to execute (a CMD_* value) + * @param err_message Message prefix to show on error * @param callback A callback function to call after the command is finished * @param company The company that wants to send the command * @param tile The tile to perform a command on (see #CommandProc) @@ -133,16 +134,15 @@ static CommandQueue _local_execution_queue; * @param p2 Additional data for the command (see #CommandProc) * @param text The text to pass */ -void NetworkSendCommand(uint32 cmd, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { - assert((cmd & CMD_FLAGS_MASK) == 0); - CommandPacket c; c.company = company; c.tile = tile; c.p1 = p1; c.p2 = p2; c.cmd = cmd; + c.err_msg = err_message; c.callback = callback; c.text = text; @@ -207,8 +207,7 @@ void NetworkExecuteLocalCommandQueue() /* We can execute this command */ _current_company = cp->company; - cp->cmd |= CMD_NETWORK_COMMAND; - DoCommandP(cp, cp->my_cmd); + DoCommandP(cp, cp->my_cmd, true); queue.Pop(); delete cp; @@ -295,10 +294,10 @@ void NetworkDistributeCommands() const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *cp) { cp->company = (CompanyID)p->Recv_uint8(); - cp->cmd = p->Recv_uint32(); + cp->cmd = static_cast(p->Recv_uint16()); if (!IsValidCommand(cp->cmd)) return "invalid command"; if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "single-player only command"; - if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag"; + cp->err_msg = p->Recv_uint16(); cp->p1 = p->Recv_uint32(); cp->p2 = p->Recv_uint32(); @@ -320,7 +319,8 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp) { p->Send_uint8 (cp->company); - p->Send_uint32(cp->cmd); + p->Send_uint16(cp->cmd); + p->Send_uint16(cp->err_msg); p->Send_uint32(cp->p1); p->Send_uint32(cp->p2); p->Send_uint32(cp->tile); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index c795e15501..82e01e81e2 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1537,7 +1537,7 @@ private: if (_network_server) { DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW, _network_own_client_id); } else { - NetworkSendCommand(CMD_COMPANY_CTRL, nullptr, _local_company, 0, CCA_NEW, 0, {}); + NetworkSendCommand(CMD_COMPANY_CTRL, STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); } } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 65e8010736..50b46dfe10 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1034,12 +1034,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER) { - IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a server only command {}.", ci->client_id, this->GetClientIP(), cp.cmd & CMD_ID_MASK); + IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a server only command {}.", ci->client_id, this->GetClientIP(), cp.cmd); return this->SendError(NETWORK_ERROR_KICKED); } if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER) { - IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a non-spectator command {}.", ci->client_id, this->GetClientIP(), cp.cmd & CMD_ID_MASK); + IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a non-spectator command {}.", ci->client_id, this->GetClientIP(), cp.cmd); return this->SendError(NETWORK_ERROR_KICKED); } @@ -2078,7 +2078,7 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci) /* ci is nullptr when replaying, or for AIs. In neither case there is a client. */ ci->client_playas = c->index; NetworkUpdateClientInfo(ci->client_id); - NetworkSendCommand(CMD_RENAME_PRESIDENT, nullptr, c->index, 0, 0, 0, ci->client_name); + NetworkSendCommand(CMD_RENAME_PRESIDENT, STR_NULL, nullptr, c->index, 0, 0, 0, ci->client_name); } /* Announce new company on network. */ diff --git a/src/object_gui.cpp b/src/object_gui.cpp index b05d46831b..234e3eab66 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -541,7 +541,7 @@ public: void OnPlaceObject(Point pt, TileIndex tile) override { ObjectClass *objclass = ObjectClass::Get(_selected_object_class); - DoCommandP(CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform, + DoCommandP(CMD_BUILD_OBJECT, STR_ERROR_CAN_T_BUILD_OBJECT, CcTerraform, tile, objclass->GetSpec(_selected_object_index)->Index(), _selected_object_view); } diff --git a/src/order_backup.cpp b/src/order_backup.cpp index e3bcb30eb5..cba46941c5 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -198,7 +198,7 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, /* We need to circumvent the "prevention" from this command being executed * while the game is paused, so use the internal method. Nor do we want * this command to get its cost estimated when shift is pressed. */ - DoCommandPInternal(CMD_CLEAR_ORDER_BACKUP, nullptr, true, false, ob->tile, 0, user, {}); + DoCommandPInternal(CMD_CLEAR_ORDER_BACKUP, STR_NULL, nullptr, true, false, false, ob->tile, 0, user, {}); } else { /* The command came from the game logic, i.e. the clearing of a tile. * In that case we have no need to actually sync this, just do it. */ diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 8ec4e7e985..b934b9d161 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -591,7 +591,7 @@ private: } if (order->GetLoadType() == load_type) return; // If we still match, do nothing - DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (load_type << 4)); + DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (load_type << 4)); } /** @@ -606,7 +606,7 @@ private: if (order == nullptr) return; i = (order->GetDepotOrderType() & ODTFB_SERVICE) ? DA_ALWAYS_GO : DA_SERVICE; } - DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4)); + DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4)); } /** @@ -621,7 +621,7 @@ private: _settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); order.SetDepotActionType(ODATFB_NEAREST_DEPOT); - DoCommandP(CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); + DoCommandP(CMD_INSERT_ORDER, STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); } /** @@ -641,7 +641,7 @@ private: } if (order->GetUnloadType() == unload_type) return; // If we still match, do nothing - DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4)); + DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4)); /* Transfer and unload orders with leave empty as default */ if (unload_type == OUFB_TRANSFER || unload_type == OUFB_UNLOAD) { @@ -669,7 +669,7 @@ private: } this->SetWidgetDirty(WID_O_NON_STOP); - DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_NON_STOP | non_stop << 4); + DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_NON_STOP | non_stop << 4); } /** @@ -682,7 +682,7 @@ private: if (_ctrl_pressed && this->vehicle->cur_implicit_order_index == this->OrderGetSel()) return; if (this->vehicle->GetNumOrders() <= 1) return; - DoCommandP(CMD_SKIP_TO_ORDER | CMD_MSG(_ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER), + DoCommandP(CMD_SKIP_TO_ORDER, _ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER, this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders())); } @@ -694,7 +694,7 @@ private: /* When networking, move one order lower */ int selected = this->selected_order + (int)_networking; - if (DoCommandP(CMD_DELETE_ORDER | CMD_MSG(STR_ERROR_CAN_T_DELETE_THIS_ORDER), this->vehicle->tile, this->vehicle->index, this->OrderGetSel())) { + if (DoCommandP(CMD_DELETE_ORDER, STR_ERROR_CAN_T_DELETE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel())) { this->selected_order = selected >= this->vehicle->GetNumOrders() ? -1 : selected; this->UpdateButtonState(); } @@ -719,7 +719,7 @@ private: /* Get another vehicle that share orders with this vehicle. */ Vehicle *other_shared = (this->vehicle->FirstShared() == this->vehicle) ? this->vehicle->NextShared() : this->vehicle->PreviousShared(); /* Copy the order list of the other vehicle. */ - if (DoCommandP(CMD_CLONE_ORDER | CMD_MSG(STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST), this->vehicle->tile, this->vehicle->index | CO_COPY << 30, other_shared->index)) { + if (DoCommandP(CMD_CLONE_ORDER, STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST, this->vehicle->tile, this->vehicle->index | CO_COPY << 30, other_shared->index)) { this->UpdateButtonState(); } } @@ -1159,7 +1159,7 @@ public: order.index = 0; order.MakeConditional(order_id); - DoCommandP(CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); + DoCommandP(CMD_INSERT_ORDER, STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); } ResetObjectToPlace(); break; @@ -1182,7 +1182,7 @@ public: this->selected_order = -1; } else if (sel == this->selected_order) { if (this->vehicle->type == VEH_TRAIN && sel < this->vehicle->GetNumOrders()) { - DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), + DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_STOP_LOCATION | ((this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END) << 4); } @@ -1331,7 +1331,7 @@ public: default: break; } - DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4); + DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4); } } @@ -1369,11 +1369,11 @@ public: break; case WID_O_COND_VARIABLE: - DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VARIABLE | index << 4); + DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VARIABLE | index << 4); break; case WID_O_COND_COMPARATOR: - DoCommandP(CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_COMPARATOR | index << 4); + DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_COMPARATOR | index << 4); break; } } @@ -1386,7 +1386,7 @@ public: VehicleOrderID to_order = this->GetOrderFromPt(pt.y); if (!(from_order == to_order || from_order == INVALID_VEH_ORDER_ID || from_order > this->vehicle->GetNumOrders() || to_order == INVALID_VEH_ORDER_ID || to_order > this->vehicle->GetNumOrders()) && - DoCommandP(CMD_MOVE_ORDER | CMD_MSG(STR_ERROR_CAN_T_MOVE_THIS_ORDER), this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16))) { + DoCommandP(CMD_MOVE_ORDER, STR_ERROR_CAN_T_MOVE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16))) { this->selected_order = -1; this->UpdateButtonState(); } @@ -1438,7 +1438,7 @@ public: const Order cmd = GetOrderCmdFromTile(this->vehicle, tile); if (cmd.IsType(OT_NOTHING)) return; - if (DoCommandP(CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack())) { + if (DoCommandP(CMD_INSERT_ORDER, STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack())) { /* With quick goto the Go To button stays active */ if (!_settings_client.gui.quick_goto) ResetObjectToPlace(); } @@ -1455,7 +1455,7 @@ public: bool share_order = _ctrl_pressed || this->goto_type == OPOS_SHARE; if (this->vehicle->GetNumOrders() != 0 && !share_order) return false; - if (DoCommandP(share_order ? CMD_CLONE_ORDER | CMD_MSG(STR_ERROR_CAN_T_SHARE_ORDER_LIST) : CMD_CLONE_ORDER | CMD_MSG(STR_ERROR_CAN_T_COPY_ORDER_LIST), + if (DoCommandP(CMD_CLONE_ORDER, share_order ? STR_ERROR_CAN_T_SHARE_ORDER_LIST : STR_ERROR_CAN_T_COPY_ORDER_LIST, this->vehicle->tile, this->vehicle->index | (share_order ? CO_SHARE : CO_COPY) << 30, v->index)) { this->selected_order = -1; ResetObjectToPlace(); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 17254ccfb0..54bef88fdf 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -85,16 +85,15 @@ static bool IsStationAvailable(const StationSpec *statspec) return Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res); } -void CcPlaySound_CONSTRUCTION_RAIL(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcPlaySound_CONSTRUCTION_RAIL(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); } static void GenericPlaceRail(TileIndex tile, int cmd) { - DoCommandP(_remove_button_clicked ? - CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) : - CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), + DoCommandP(_remove_button_clicked ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL, + _remove_button_clicked ? STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK : STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3)); } @@ -129,7 +128,7 @@ static const DiagDirection _place_depot_extra_dir[12] = { DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_NW, DIAGDIR_NE, }; -void CcRailDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcRailDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -166,11 +165,11 @@ static void PlaceRail_Waypoint(TileIndex tile) } else { /* Tile where we can't build rail waypoints. This is always going to fail, * but provides the user with a proper error message. */ - DoCommandP(CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT), tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16); + DoCommandP(CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16); } } -void CcStation(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcStation(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -199,7 +198,7 @@ static void PlaceRail_Station(TileIndex tile) int h = _settings_client.gui.station_platlength; if (!_railstation.orientation) Swap(w, h); - CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" }; + CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, "" }; ShowSelectStationIfNeeded(cmdcont, TileArea(tile, w, h)); } } @@ -224,7 +223,7 @@ static void GenericPlaceSignals(TileIndex tile) Track track = FindFirstTrack(trackbits); if (_remove_button_clicked) { - DoCommandP(CMD_REMOVE_SIGNALS | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM), CcPlaySound_CONSTRUCTION_RAIL, tile, track, 0); + DoCommandP(CMD_REMOVE_SIGNALS, STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, tile, track, 0); } else { const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0); @@ -255,7 +254,7 @@ static void GenericPlaceSignals(TileIndex tile) SB(p1, 9, 6, cycle_types); } - DoCommandP(CMD_BUILD_SIGNALS | CMD_MSG((w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE), + DoCommandP(CMD_BUILD_SIGNALS, (w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL, tile, p1, 0); } } @@ -277,7 +276,7 @@ static void PlaceRail_Bridge(TileIndex tile, Window *w) } /** Command callback for building a tunnel */ -void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); @@ -358,9 +357,8 @@ static void BuildRailClick_Remove(Window *w) static void DoRailroadTrack(int mode) { uint32 p2 = _cur_railtype | (mode << 6) | (_settings_client.gui.auto_remove_signals << 11); - DoCommandP(_remove_button_clicked ? - CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) : - CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK), + DoCommandP(_remove_button_clicked ? CMD_REMOVE_RAILROAD_TRACK : CMD_BUILD_RAILROAD_TRACK, + _remove_button_clicked ? STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK : STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2); } @@ -413,9 +411,8 @@ static void HandleAutoSignalPlacement() /* _settings_client.gui.drag_signals_density is given as a parameter such that each user * in a network game can specify their own signal density */ - DoCommandP(_remove_button_clicked ? - CMD_REMOVE_SIGNAL_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM) : - CMD_BUILD_SIGNAL_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE), + DoCommandP(_remove_button_clicked ? CMD_REMOVE_SIGNAL_TRACK : CMD_BUILD_SIGNAL_TRACK, + _remove_button_clicked ? STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL, TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2); } @@ -643,7 +640,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_DEPOT: - DoCommandP(CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT), + DoCommandP(CMD_BUILD_TRAIN_DEPOT, STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, CcRailDepot, tile, _cur_railtype, _build_depot_direction); break; @@ -664,7 +661,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_TUNNEL: - DoCommandP(CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRailTunnel, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0); + DoCommandP(CMD_BUILD_TUNNEL, STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0); break; case WID_RAT_CONVERT_RAIL: @@ -706,7 +703,7 @@ struct BuildRailToolbarWindow : Window { break; case DDSP_CONVERT_RAIL: - DoCommandP(CMD_CONVERT_RAIL | CMD_MSG(STR_ERROR_CAN_T_CONVERT_RAIL), CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0)); + DoCommandP(CMD_CONVERT_RAIL, STR_ERROR_CAN_T_CONVERT_RAIL, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0)); break; case DDSP_REMOVE_STATION: @@ -714,20 +711,20 @@ struct BuildRailToolbarWindow : Window { if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) { /* Station */ if (_remove_button_clicked) { - DoCommandP(CMD_REMOVE_FROM_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION), CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); + DoCommandP(CMD_REMOVE_FROM_RAIL_STATION, STR_ERROR_CAN_T_REMOVE_PART_OF_STATION, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); } else { HandleStationPlacement(start_tile, end_tile); } } else { /* Waypoint */ if (_remove_button_clicked) { - DoCommandP(CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT), CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); + DoCommandP(CMD_REMOVE_FROM_RAIL_WAYPOINT, STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); } else { TileArea ta(start_tile, end_tile); uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 6 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24; uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16; - CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT), CcPlaySound_CONSTRUCTION_RAIL, "" }; + CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, "" }; ShowSelectWaypointIfNeeded(cmdcont, ta); } } @@ -886,7 +883,7 @@ static void HandleStationPlacement(TileIndex start, TileIndex end) uint32 p1 = _cur_railtype | _railstation.orientation << 6 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24; uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16; - CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" }; + CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, "" }; ShowSelectStationIfNeeded(cmdcont, ta); } diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 84ec742068..bdd4353ca8 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -66,7 +66,7 @@ static RoadType _cur_roadtype; static DiagDirection _road_depot_orientation; static DiagDirection _road_station_picker_orientation; -void CcPlaySound_CONSTRUCTION_OTHER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcPlaySound_CONSTRUCTION_OTHER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); } @@ -96,7 +96,7 @@ static void PlaceRoad_Bridge(TileIndex tile, Window *w) * @param p2 unused * @param cmd unused */ -void CcBuildRoadTunnel(const CommandCost &result, TileIndex start_tile, uint32 p1, uint32 p2, uint32 cmd) +void CcBuildRoadTunnel(const CommandCost &result, TileIndex start_tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, start_tile); @@ -129,7 +129,7 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) } } -void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -155,7 +155,7 @@ void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 * @param cmd Unused. * @see CmdBuildRoadStop */ -void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -178,9 +178,10 @@ void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, * bit 2: Allow stations directly adjacent to other stations. * bit 5..10: The roadtypes. * @param cmd Command to use. + * @param err_msg Error message to show. * @see CcRoadStop() */ -static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, uint32 cmd) +static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, Commands cmd, StringID err_msg) { uint8 ddir = _road_station_picker_orientation; SB(p2, 16, 16, INVALID_STATION); // no station to join @@ -192,7 +193,7 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, u p2 |= ddir << 3; // Set the DiagDirecion into p2 bits 3 and 4. TileArea ta(start_tile, end_tile); - CommandContainer cmdcont = { ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, CcRoadStop, "" }; + CommandContainer cmdcont = { ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, err_msg, CcRoadStop, "" }; ShowSelectStationIfNeeded(cmdcont, ta); } @@ -550,7 +551,7 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_DEPOT: - DoCommandP(CMD_BUILD_ROAD_DEPOT | CMD_MSG(this->rti->strings.err_depot), CcRoadDepot, + DoCommandP(CMD_BUILD_ROAD_DEPOT, this->rti->strings.err_depot, CcRoadDepot, tile, _cur_roadtype << 2 | _road_depot_orientation, 0); break; @@ -567,7 +568,7 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_BUILD_TUNNEL: - DoCommandP(CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel, + DoCommandP(CMD_BUILD_TUNNEL, STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRoadTunnel, tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0); break; @@ -669,9 +670,8 @@ struct BuildRoadToolbarWindow : Window { * flags */ _place_road_flag = (RoadFlags)((_place_road_flag & RF_DIR_Y) ? (_place_road_flag & 0x07) : (_place_road_flag >> 3)); - DoCommandP(_remove_button_clicked ? - CMD_REMOVE_LONG_ROAD | CMD_MSG(this->rti->strings.err_remove_road) : - CMD_BUILD_LONG_ROAD | CMD_MSG(this->rti->strings.err_build_road), CcPlaySound_CONSTRUCTION_OTHER, + DoCommandP(_remove_button_clicked ? CMD_REMOVE_LONG_ROAD : CMD_BUILD_LONG_ROAD, + _remove_button_clicked ? this->rti->strings.err_remove_road : this->rti->strings.err_build_road, CcPlaySound_CONSTRUCTION_OTHER, start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10)); break; @@ -680,9 +680,9 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_BUS_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_BUS]), CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS); + DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS); } else { - PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(this->rti->strings.err_build_station[ROADSTOP_BUS])); + PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP, this->rti->strings.err_build_station[ROADSTOP_BUS]); } } break; @@ -692,15 +692,15 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK); + DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK); } else { - PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP | CMD_MSG(this->rti->strings.err_build_station[ROADSTOP_TRUCK])); + PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP, this->rti->strings.err_build_station[ROADSTOP_TRUCK]); } } break; case DDSP_CONVERT_ROAD: - DoCommandP(CMD_CONVERT_ROAD | CMD_MSG(rti->strings.err_convert_road), CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype); + DoCommandP(CMD_CONVERT_ROAD, rti->strings.err_convert_road, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype); break; } } diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index bb7260d9c5..720e922f12 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -82,24 +82,24 @@ ScriptObject::ActiveInstance::~ActiveInstance() return GetStorage()->mode_instance; } -/* static */ void ScriptObject::SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +/* static */ void ScriptObject::SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { ScriptStorage *s = GetStorage(); Debug(script, 6, "SetLastCommand company={:02d} tile={:06x} p1={:08x} p2={:08x} cmd={}", s->root_company, tile, p1, p2, cmd); s->last_tile = tile; s->last_p1 = p1; s->last_p2 = p2; - s->last_cmd = cmd & CMD_ID_MASK; + s->last_cmd = cmd; } -/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { ScriptStorage *s = GetStorage(); Debug(script, 6, "CheckLastCommand company={:02d} tile={:06x} p1={:08x} p2={:08x} cmd={}", s->root_company, tile, p1, p2, cmd); if (s->last_tile != tile) return false; if (s->last_p1 != p1) return false; if (s->last_p2 != p2) return false; - if (s->last_cmd != (cmd & CMD_ID_MASK)) return false; + if (s->last_cmd != cmd) return false; return true; } @@ -298,7 +298,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() return GetStorage()->callback_value[index]; } -/* static */ bool ScriptObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text, Script_SuspendCallbackProc *callback) +/* static */ bool ScriptObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd, const char *text, Script_SuspendCallbackProc *callback) { if (!ScriptObject::CanSuspend()) { throw Script_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator."); @@ -329,7 +329,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() if (!estimate_only && _networking && !_generating_world) SetLastCommand(tile, p1, p2, cmd); /* Try to perform the command. */ - CommandCost res = ::DoCommandPInternal(cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, false, estimate_only, tile, p1, p2, command_text); + CommandCost res = ::DoCommandPInternal(cmd, STR_NULL, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, false, estimate_only, false, tile, p1, p2, command_text); /* We failed; set the error and bail out */ if (res.Failed()) { diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index f953b20e47..a1134aa5c3 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -13,6 +13,7 @@ #include "../../misc/countedptr.hpp" #include "../../road_type.h" #include "../../rail_type.h" +#include "../../command_type.h" #include "script_types.hpp" #include "../script_suspend.hpp" @@ -69,17 +70,17 @@ protected: /** * Executes a raw DoCommand for the script. */ - static bool DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text = nullptr, Script_SuspendCallbackProc *callback = nullptr); + static bool DoCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd, const char *text = nullptr, Script_SuspendCallbackProc *callback = nullptr); /** * Store the latest command executed by the script. */ - static void SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd); + static void SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd); /** * Check if it's the latest command executed by the script. */ - static bool CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd); + static bool CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd); /** * Sets the DoCommand costs counter to a value. diff --git a/src/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp index bbd9df55de..9e2a56e923 100644 --- a/src/script/api/script_vehicle.cpp +++ b/src/script/api/script_vehicle.cpp @@ -69,7 +69,7 @@ EnforcePreconditionCustomError(VEHICLE_INVALID, !ScriptGameSettings::IsDisabledVehicleType((ScriptVehicle::VehicleType)type), ScriptVehicle::ERR_VEHICLE_BUILD_DISABLED); - if (!ScriptObject::DoCommand(depot, engine_id | (cargo << 24), 0, ::GetCmdBuildVeh(type), nullptr, &ScriptInstance::DoCommandReturnVehicleID)) return VEHICLE_INVALID; + if (!ScriptObject::DoCommand(depot, engine_id | (cargo << 24), 0, CMD_BUILD_VEHICLE, nullptr, &ScriptInstance::DoCommandReturnVehicleID)) return VEHICLE_INVALID; /* In case of test-mode, we return VehicleID 0 */ return 0; @@ -91,9 +91,7 @@ if (!ScriptEngine::IsBuildable(engine_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; - ::VehicleType type = ::Engine::Get(engine_id)->type; - - CommandCost res = ::DoCommand(DC_QUERY_COST, ::GetCmdBuildVeh(type), depot, engine_id | (cargo << 24), 0); + CommandCost res = ::DoCommand(DC_QUERY_COST, CMD_BUILD_VEHICLE, depot, engine_id | (cargo << 24), 0); return res.Succeeded() ? _returned_refit_capacity : -1; } @@ -142,7 +140,7 @@ if (!IsValidVehicle(vehicle_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; - CommandCost res = ::DoCommand(DC_QUERY_COST, GetCmdRefitVeh(::Vehicle::Get(vehicle_id)), 0, vehicle_id, cargo); + CommandCost res = ::DoCommand(DC_QUERY_COST, CMD_REFIT_VEHICLE, 0, vehicle_id, cargo); return res.Succeeded() ? _returned_refit_capacity : -1; } @@ -151,7 +149,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id) && ScriptCargo::IsValidCargo(cargo)); - return ScriptObject::DoCommand(0, vehicle_id, cargo, GetCmdRefitVeh(::Vehicle::Get(vehicle_id))); + return ScriptObject::DoCommand(0, vehicle_id, cargo, CMD_REFIT_VEHICLE); } @@ -161,7 +159,7 @@ EnforcePrecondition(false, IsValidVehicle(vehicle_id)); const Vehicle *v = ::Vehicle::Get(vehicle_id); - return ScriptObject::DoCommand(0, vehicle_id | (v->type == VEH_TRAIN ? 1 : 0) << 20, 0, GetCmdSellVeh(v)); + return ScriptObject::DoCommand(0, vehicle_id | (v->type == VEH_TRAIN ? 1 : 0) << 20, 0, CMD_SELL_VEHICLE); } /* static */ bool ScriptVehicle::_SellWagonInternal(VehicleID vehicle_id, int wagon, bool sell_attached_wagons) @@ -191,7 +189,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - return ScriptObject::DoCommand(0, vehicle_id, 0, GetCmdSendToDepot(::Vehicle::Get(vehicle_id))); + return ScriptObject::DoCommand(0, vehicle_id, 0, CMD_SEND_VEHICLE_TO_DEPOT); } /* static */ bool ScriptVehicle::SendVehicleToDepotForServicing(VehicleID vehicle_id) @@ -199,7 +197,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - return ScriptObject::DoCommand(0, vehicle_id | DEPOT_SERVICE, 0, GetCmdSendToDepot(::Vehicle::Get(vehicle_id))); + return ScriptObject::DoCommand(0, vehicle_id | DEPOT_SERVICE, 0, CMD_SEND_VEHICLE_TO_DEPOT); } /* static */ bool ScriptVehicle::IsInDepot(VehicleID vehicle_id) diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index 4342289afc..03fad1491a 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -687,7 +687,7 @@ SQInteger ScriptInstance::GetOpsTillSuspend() return this->engine->GetOpsTillSuspend(); } -bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { ScriptObject::ActiveInstance active(this); diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp index 7db4f5ea8f..01415d4d4b 100644 --- a/src/script/script_instance.hpp +++ b/src/script/script_instance.hpp @@ -183,7 +183,7 @@ public: * @param cmd cmd as given to DoCommandPInternal. * @return true if we handled result. */ - bool DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd); + bool DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd); /** * Insert an event for this script. diff --git a/src/script/script_storage.hpp b/src/script/script_storage.hpp index 2f5520cffa..8dadf59ae4 100644 --- a/src/script/script_storage.hpp +++ b/src/script/script_storage.hpp @@ -47,7 +47,7 @@ private: TileIndex last_tile; ///< The last tile passed to a command. uint32 last_p1; ///< The last p1 passed to a command. uint32 last_p2; ///< The last p2 passed to a command. - uint32 last_cmd; ///< The last cmd passed to a command. + Commands last_cmd; ///< The last cmd passed to a command. VehicleID new_vehicle_id; ///< The ID of the new Vehicle. SignID new_sign_id; ///< The ID of the new Sign. diff --git a/src/settings.cpp b/src/settings.cpp index d821239fbb..b82fe6d9a1 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1603,7 +1603,7 @@ void SyncCompanySettings() const SettingDesc *sd = GetSettingDesc(desc); uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object); uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object); - if (old_value != new_value) NetworkSendCommand(CMD_CHANGE_COMPANY_SETTING, nullptr, _local_company, 0, 0, new_value, sd->GetName()); + if (old_value != new_value) NetworkSendCommand(CMD_CHANGE_COMPANY_SETTING, STR_NULL, nullptr, _local_company, 0, 0, new_value, sd->GetName()); } } diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index 77c5ce456c..504bae0781 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -114,7 +114,7 @@ CommandCost CmdRenameSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 * @param p2 unused * @param cmd unused */ -void CcPlaceSign(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcPlaceSign(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -130,5 +130,5 @@ void CcPlaceSign(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 */ void PlaceProc_Sign(TileIndex tile) { - DoCommandP(CMD_PLACE_SIGN | CMD_MSG(STR_ERROR_CAN_T_PLACE_SIGN_HERE), CcPlaceSign, tile, 0, 0); + DoCommandP(CMD_PLACE_SIGN, STR_ERROR_CAN_T_PLACE_SIGN_HERE, CcPlaceSign, tile, 0, 0); } diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 368b57b43e..0bb9fa2daf 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -413,7 +413,7 @@ Window *ShowSignList() static bool RenameSign(SignID index, const char *text) { bool remove = StrEmpty(text); - DoCommandP(CMD_RENAME_SIGN | (StrEmpty(text) ? CMD_MSG(STR_ERROR_CAN_T_DELETE_SIGN) : CMD_MSG(STR_ERROR_CAN_T_CHANGE_SIGN_NAME)), 0, index, 0, text); + DoCommandP(CMD_RENAME_SIGN, StrEmpty(text) ? STR_ERROR_CAN_T_DELETE_SIGN : STR_ERROR_CAN_T_CHANGE_SIGN_NAME, 0, index, 0, text); return remove; } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 1992a2c56c..e1229fe3d1 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -2084,7 +2084,7 @@ struct StationViewWindow : public Window { { if (str == nullptr) return; - DoCommandP(CMD_RENAME_STATION | CMD_MSG(STR_ERROR_CAN_T_RENAME_STATION), 0, this->window_number, 0, str); + DoCommandP(CMD_RENAME_STATION, STR_ERROR_CAN_T_RENAME_STATION, 0, this->window_number, 0, str); } void OnResize() override diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 5e25df78ca..0325a957ff 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -39,7 +39,7 @@ #include "safeguards.h" -void CcTerraform(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcTerraform(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); @@ -115,16 +115,16 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t switch (proc) { case DDSP_DEMOLISH_AREA: - DoCommandP(CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed ? 1 : 0); + DoCommandP(CMD_CLEAR_AREA, STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed ? 1 : 0); break; case DDSP_RAISE_AND_LEVEL_AREA: - DoCommandP(CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_RAISE_LAND_HERE), CcTerraform, end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0)); + DoCommandP(CMD_LEVEL_LAND, STR_ERROR_CAN_T_RAISE_LAND_HERE, CcTerraform, end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0)); break; case DDSP_LOWER_AND_LEVEL_AREA: - DoCommandP(CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_LOWER_LAND_HERE), CcTerraform, end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0)); + DoCommandP(CMD_LEVEL_LAND, STR_ERROR_CAN_T_LOWER_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0)); break; case DDSP_LEVEL_AREA: - DoCommandP(CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_LEVEL_LAND_HERE), CcTerraform, end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0)); + DoCommandP(CMD_LEVEL_LAND, STR_ERROR_CAN_T_LEVEL_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0)); break; case DDSP_CREATE_ROCKS: GenerateRockyArea(end_tile, start_tile); @@ -238,7 +238,7 @@ struct TerraformToolbarWindow : Window { break; case WID_TT_BUY_LAND: // Buy land button - DoCommandP(CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_PURCHASE_THIS_LAND), CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0); + DoCommandP(CMD_BUILD_OBJECT, STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0); break; case WID_TT_PLACE_SIGN: // Place sign button @@ -395,7 +395,7 @@ static void CommonRaiseLowerBigLand(TileIndex tile, int mode) StringID msg = mode ? STR_ERROR_CAN_T_RAISE_LAND_HERE : STR_ERROR_CAN_T_LOWER_LAND_HERE; - DoCommandP(CMD_TERRAFORM_LAND | CMD_MSG(msg), CcTerraform, tile, SLOPE_N, (uint32)mode); + DoCommandP(CMD_TERRAFORM_LAND, msg, CcTerraform, tile, SLOPE_N, (uint32)mode); } else { assert(_terraform_size != 0); TileArea ta(tile, _terraform_size, _terraform_size); diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 9f9bfad5a6..00ab50115d 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -142,7 +142,7 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID */ static void ChangeTimetableStartCallback(const Window *w, Date date) { - DoCommandP(CMD_SET_TIMETABLE_START | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, w->window_number, date); + DoCommandP(CMD_SET_TIMETABLE_START, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, w->window_number, date); } @@ -578,25 +578,25 @@ struct TimetableWindow : Window { case WID_VT_CLEAR_TIME: { // Clear waiting time. uint32 p1 = PackTimetableArgs(v, this->sel_index, false); - DoCommandP(CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, p1, 0); + DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, 0); break; } case WID_VT_CLEAR_SPEED: { // Clear max speed button. uint32 p1 = PackTimetableArgs(v, this->sel_index, true); - DoCommandP(CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, p1, UINT16_MAX); + DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, UINT16_MAX); break; } case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter. - DoCommandP(CMD_SET_VEHICLE_ON_TIME | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, v->index, 0); + DoCommandP(CMD_SET_VEHICLE_ON_TIME, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, 0); break; case WID_VT_AUTOFILL: { // Autofill the timetable. uint32 p2 = 0; if (!HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(p2, 0); if (_ctrl_pressed) SetBit(p2, 1); - DoCommandP(CMD_AUTOFILL_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, v->index, p2); + DoCommandP(CMD_AUTOFILL_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, p2); break; } @@ -629,7 +629,7 @@ struct TimetableWindow : Window { uint32 p2 = std::min(val, UINT16_MAX); - DoCommandP(CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), 0, p1, p2); + DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, p2); } void OnResize() override diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 9082fc7b38..9e1ba39680 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -287,7 +287,7 @@ public: } case WID_TA_EXECUTE: - DoCommandP(CMD_DO_TOWN_ACTION | CMD_MSG(STR_ERROR_CAN_T_DO_THIS), this->town->xy, this->window_number, this->sel_index); + DoCommandP(CMD_DO_TOWN_ACTION, STR_ERROR_CAN_T_DO_THIS, this->town->xy, this->window_number, this->sel_index); break; } } @@ -474,12 +474,12 @@ public: _warn_town_no_roads = true; } - DoCommandP(CMD_EXPAND_TOWN | CMD_MSG(STR_ERROR_CAN_T_EXPAND_TOWN), 0, this->window_number, 0); + DoCommandP(CMD_EXPAND_TOWN, STR_ERROR_CAN_T_EXPAND_TOWN, 0, this->window_number, 0); break; } case WID_TV_DELETE: // delete town - only available on Scenario editor - DoCommandP(CMD_DELETE_TOWN | CMD_MSG(STR_ERROR_TOWN_CAN_T_DELETE), 0, this->window_number, 0); + DoCommandP(CMD_DELETE_TOWN, STR_ERROR_TOWN_CAN_T_DELETE, 0, this->window_number, 0); break; } } @@ -561,7 +561,7 @@ public: { if (str == nullptr) return; - DoCommandP(CMD_RENAME_TOWN | CMD_MSG(STR_ERROR_CAN_T_RENAME_TOWN), 0, this->window_number, 0, str); + DoCommandP(CMD_RENAME_TOWN, STR_ERROR_CAN_T_RENAME_TOWN, 0, this->window_number, 0, str); } }; @@ -1008,7 +1008,7 @@ void ShowTownDirectory() new TownDirectoryWindow(&_town_directory_desc); } -void CcFoundTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcFoundTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -1016,7 +1016,7 @@ void CcFoundTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } -void CcFoundRandomTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcFoundRandomTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Succeeded()) ScrollMainWindowToTile(Town::Get(_new_town_id)->xy); } @@ -1162,7 +1162,7 @@ public: if (strcmp(buf, this->townname_editbox.text.buf) != 0) name = this->townname_editbox.text.buf; } - bool success = DoCommandP(CMD_FOUND_TOWN | CMD_MSG(errstr), cc, + bool success = DoCommandP(CMD_FOUND_TOWN, errstr, cc, tile, this->town_size | this->city << 2 | this->town_layout << 3 | random << 6, townnameparts, name); /* Rerandomise name, if success and no cost-estimation. */ diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 9bb7d59476..a630c9fbd1 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -27,7 +27,7 @@ * @param p2 Additional data for the command (for the #CommandProc) * @param cmd Unused. */ -void CcBuildWagon(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcBuildWagon(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index 005cebd467..f176668b1a 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -240,7 +240,7 @@ public: void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL && pt.x != -1 && select_proc == DDSP_PLANT_TREES) { - DoCommandP(CMD_PLANT_TREE | CMD_MSG(STR_ERROR_CAN_T_PLANT_TREE_HERE), end_tile, this->tree_to_plant, start_tile); + DoCommandP(CMD_PLANT_TREE, STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, this->tree_to_plant, start_tile); } } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 1e0cccaadc..82170ed4c0 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1561,7 +1561,7 @@ void VehicleEnterDepot(Vehicle *v) if (v->current_order.IsRefit()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - CommandCost cost = DoCommand(DC_EXEC, GetCmdRefitVeh(v), v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8); + CommandCost cost = DoCommand(DC_EXEC, CMD_REFIT_VEHICLE, v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8); cur_company.Restore(); if (cost.Failed()) { diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 5b1878c3a8..a36abb59dd 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -37,33 +37,33 @@ #include "safeguards.h" -/* Tables used in vehicle.h to find the right command for a certain vehicle type */ -const uint32 _veh_build_proc_table[] = { - CMD_BUILD_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN), - CMD_BUILD_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_ROAD_VEHICLE), - CMD_BUILD_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_SHIP), - CMD_BUILD_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_AIRCRAFT), +/* Tables used in vehicle_func.h to find the right error message for a certain vehicle type */ +const StringID _veh_build_msg_table[] = { + STR_ERROR_CAN_T_BUY_TRAIN, + STR_ERROR_CAN_T_BUY_ROAD_VEHICLE, + STR_ERROR_CAN_T_BUY_SHIP, + STR_ERROR_CAN_T_BUY_AIRCRAFT, }; -const uint32 _veh_sell_proc_table[] = { - CMD_SELL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_SELL_TRAIN), - CMD_SELL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_SELL_ROAD_VEHICLE), - CMD_SELL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_SELL_SHIP), - CMD_SELL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_SELL_AIRCRAFT), +const StringID _veh_sell_msg_table[] = { + STR_ERROR_CAN_T_SELL_TRAIN, + STR_ERROR_CAN_T_SELL_ROAD_VEHICLE, + STR_ERROR_CAN_T_SELL_SHIP, + STR_ERROR_CAN_T_SELL_AIRCRAFT, }; -const uint32 _veh_refit_proc_table[] = { - CMD_REFIT_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_REFIT_TRAIN), - CMD_REFIT_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_REFIT_ROAD_VEHICLE), - CMD_REFIT_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_REFIT_SHIP), - CMD_REFIT_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_REFIT_AIRCRAFT), +const StringID _veh_refit_msg_table[] = { + STR_ERROR_CAN_T_REFIT_TRAIN, + STR_ERROR_CAN_T_REFIT_ROAD_VEHICLE, + STR_ERROR_CAN_T_REFIT_SHIP, + STR_ERROR_CAN_T_REFIT_AIRCRAFT, }; -const uint32 _send_to_depot_proc_table[] = { - CMD_SEND_VEHICLE_TO_DEPOT | CMD_MSG(STR_ERROR_CAN_T_SEND_TRAIN_TO_DEPOT), - CMD_SEND_VEHICLE_TO_DEPOT | CMD_MSG(STR_ERROR_CAN_T_SEND_ROAD_VEHICLE_TO_DEPOT), - CMD_SEND_VEHICLE_TO_DEPOT | CMD_MSG(STR_ERROR_CAN_T_SEND_SHIP_TO_DEPOT), - CMD_SEND_VEHICLE_TO_DEPOT | CMD_MSG(STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR), +const StringID _send_to_depot_msg_table[] = { + STR_ERROR_CAN_T_SEND_TRAIN_TO_DEPOT, + STR_ERROR_CAN_T_SEND_ROAD_VEHICLE_TO_DEPOT, + STR_ERROR_CAN_T_SEND_SHIP_TO_DEPOT, + STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR, }; @@ -182,7 +182,7 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /* If we are not in DC_EXEC undo everything */ if (flags != subflags) { - DoCommand(DC_EXEC, GetCmdSellVeh(v), 0, v->index, 0); + DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, v->index, 0); } } @@ -689,15 +689,13 @@ CommandCost CmdDepotSellAllVehicles(TileIndex tile, DoCommandFlag flags, uint32 if (!IsCompanyBuildableVehicleType(vehicle_type)) return CMD_ERROR; - uint sell_command = GetCmdSellVeh(vehicle_type); - /* Get the list of vehicles in the depot */ BuildDepotVehicleList(vehicle_type, tile, &list, &list); CommandCost last_error = CMD_ERROR; bool had_success = false; for (uint i = 0; i < list.size(); i++) { - CommandCost ret = DoCommand(flags, sell_command, tile, list[i]->index | (1 << 20), 0); + CommandCost ret = DoCommand(flags, CMD_SELL_VEHICLE, tile, list[i]->index | (1 << 20), 0); if (ret.Succeeded()) { cost.AddCost(ret); had_success = true; @@ -875,11 +873,11 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint DoCommandFlag build_flags = flags; if ((flags & DC_EXEC) && !v->IsPrimaryVehicle()) build_flags |= DC_AUTOREPLACE; - CommandCost cost = DoCommand(build_flags, GetCmdBuildVeh(v), tile, v->engine_type | (1 << 16) | (CT_INVALID << 24), 0); + CommandCost cost = DoCommand(build_flags, CMD_BUILD_VEHICLE, tile, v->engine_type | (1 << 16) | (CT_INVALID << 24), 0); if (cost.Failed()) { /* Can't build a part, then sell the stuff we already made; clear up the mess */ - if (w_front != nullptr) DoCommand(flags, GetCmdSellVeh(w_front), w_front->tile, w_front->index | (1 << 20), 0); + if (w_front != nullptr) DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w_front->index | (1 << 20), 0); return cost; } @@ -899,8 +897,8 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint if (result.Failed()) { /* The train can't be joined to make the same consist as the original. * Sell what we already made (clean up) and return an error. */ - DoCommand(flags, GetCmdSellVeh(w_front), w_front->tile, w_front->index | 1 << 20, 0); - DoCommand(flags, GetCmdSellVeh(w) , w_front->tile, w->index | 1 << 20, 0); + DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w_front->index | 1 << 20, 0); + DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w->index | 1 << 20, 0); return result; // return error and the message returned from CMD_MOVE_RAIL_VEHICLE } } else { @@ -943,7 +941,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /* Find out what's the best sub type */ byte subtype = GetBestFittingSubType(v, w, v->cargo_type); if (w->cargo_type != v->cargo_type || w->cargo_subtype != subtype) { - CommandCost cost = DoCommand(flags, GetCmdRefitVeh(v), 0, w->index, v->cargo_type | 1U << 25 | (subtype << 8)); + CommandCost cost = DoCommand(flags, CMD_REFIT_VEHICLE, 0, w->index, v->cargo_type | 1U << 25 | (subtype << 8)); if (cost.Succeeded()) total_cost.AddCost(cost); } @@ -981,7 +979,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint CommandCost result = DoCommand(flags, CMD_CLONE_ORDER, 0, w_front->index | (p2 & 1 ? CO_SHARE : CO_COPY) << 30, v_front->index); if (result.Failed()) { /* The vehicle has already been bought, so now it must be sold again. */ - DoCommand(flags, GetCmdSellVeh(w_front), w_front->tile, w_front->index | 1 << 20, 0); + DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w_front->index | 1 << 20, 0); return result; } @@ -992,7 +990,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint * check whether the company has enough money manually. */ if (!CheckCompanyHasMoney(total_cost)) { /* The vehicle has already been bought, so now it must be sold again. */ - DoCommand(flags, GetCmdSellVeh(w_front), w_front->tile, w_front->index | 1 << 20, 0); + DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w_front->index | 1 << 20, 0); return total_cost; } } @@ -1017,7 +1015,7 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con bool had_success = false; for (uint i = 0; i < list.size(); i++) { const Vehicle *v = list[i]; - CommandCost ret = DoCommand(flags, GetCmdSendToDepot(vli.vtype), v->tile, v->index | (service ? DEPOT_SERVICE : 0U) | DEPOT_DONT_CANCEL, 0); + CommandCost ret = DoCommand(flags, CMD_SEND_VEHICLE_TO_DEPOT, v->tile, v->index | (service ? DEPOT_SERVICE : 0U) | DEPOT_DONT_CANCEL, 0); if (ret.Succeeded()) { had_success = true; diff --git a/src/vehicle_func.h b/src/vehicle_func.h index ec14e526af..5784de1081 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -115,50 +115,50 @@ const struct Livery *GetEngineLivery(EngineID engine_type, CompanyID company, En SpriteID GetEnginePalette(EngineID engine_type, CompanyID company); SpriteID GetVehiclePalette(const Vehicle *v); -extern const uint32 _veh_build_proc_table[]; -extern const uint32 _veh_sell_proc_table[]; -extern const uint32 _veh_refit_proc_table[]; -extern const uint32 _send_to_depot_proc_table[]; +extern const StringID _veh_build_msg_table[]; +extern const StringID _veh_sell_msg_table[]; +extern const StringID _veh_refit_msg_table[]; +extern const StringID _send_to_depot_msg_table[]; /* Functions to find the right command for certain vehicle type */ -static inline uint32 GetCmdBuildVeh(VehicleType type) +static inline StringID GetCmdBuildVehMsg(VehicleType type) { - return _veh_build_proc_table[type]; + return _veh_build_msg_table[type]; } -static inline uint32 GetCmdBuildVeh(const BaseVehicle *v) +static inline StringID GetCmdBuildVehMsg(const BaseVehicle *v) { - return GetCmdBuildVeh(v->type); + return GetCmdBuildVehMsg(v->type); } -static inline uint32 GetCmdSellVeh(VehicleType type) +static inline StringID GetCmdSellVehMsg(VehicleType type) { - return _veh_sell_proc_table[type]; + return _veh_sell_msg_table[type]; } -static inline uint32 GetCmdSellVeh(const BaseVehicle *v) +static inline StringID GetCmdSellVehMsg(const BaseVehicle *v) { - return GetCmdSellVeh(v->type); + return GetCmdSellVehMsg(v->type); } -static inline uint32 GetCmdRefitVeh(VehicleType type) +static inline StringID GetCmdRefitVehMsg(VehicleType type) { - return _veh_refit_proc_table[type]; + return _veh_refit_msg_table[type]; } -static inline uint32 GetCmdRefitVeh(const BaseVehicle *v) +static inline StringID GetCmdRefitVehMsg(const BaseVehicle *v) { - return GetCmdRefitVeh(v->type); + return GetCmdRefitVehMsg(v->type); } -static inline uint32 GetCmdSendToDepot(VehicleType type) +static inline StringID GetCmdSendToDepotMsg(VehicleType type) { - return _send_to_depot_proc_table[type]; + return _send_to_depot_msg_table[type]; } -static inline uint32 GetCmdSendToDepot(const BaseVehicle *v) +static inline StringID GetCmdSendToDepotMsg(const BaseVehicle *v) { - return GetCmdSendToDepot(v->type); + return GetCmdSendToDepotMsg(v->type); } CommandCost EnsureNoVehicleOnGround(TileIndex tile); diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 56e1bb713b..69fb158460 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -772,7 +772,7 @@ struct RefitWindow : public Window { { assert(_current_company == _local_company); Vehicle *v = Vehicle::Get(this->window_number); - CommandCost cost = DoCommand(DC_QUERY_COST, GetCmdRefitVeh(v->type), v->tile, this->selected_vehicle, option->cargo | + CommandCost cost = DoCommand(DC_QUERY_COST, CMD_REFIT_VEHICLE, v->tile, this->selected_vehicle, option->cargo | option->subtype << 8 | this->num_vehicles << 16 | (int)this->auto_refit << 24); if (cost.Failed()) return INVALID_STRING_ID; @@ -1033,7 +1033,7 @@ struct RefitWindow : public Window { if (this->order == INVALID_VEH_ORDER_ID) { bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX; - if (DoCommandP(GetCmdRefitVeh(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16) && delete_window) this->Close(); + if (DoCommandP(CMD_REFIT_VEHICLE, GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16) && delete_window) this->Close(); } else { if (DoCommandP(CMD_ORDER_REFIT, v->tile, v->index, this->cargo->cargo | this->order << 16)) this->Close(); } @@ -1919,7 +1919,7 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: // Send to Depots - DoCommandP(GetCmdSendToDepot(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number); + DoCommandP(CMD_SEND_VEHICLE_TO_DEPOT, GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number); break; default: NOT_REACHED(); @@ -2422,7 +2422,7 @@ struct VehicleDetailsWindow : Window { mod = GetServiceIntervalClamped(mod + v->GetServiceInterval(), v->ServiceIntervalIsPercent()); if (mod == v->GetServiceInterval()) return; - DoCommandP(CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SERVICING), v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17)); + DoCommandP(CMD_CHANGE_SERVICE_INT, STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17)); break; } @@ -2458,7 +2458,7 @@ struct VehicleDetailsWindow : Window { bool iscustom = index != 0; bool ispercent = iscustom ? (index == 2) : Company::Get(v->owner)->settings.vehicle.servint_ispercent; uint16 interval = GetServiceIntervalClamped(v->GetServiceInterval(), ispercent); - DoCommandP(CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SERVICING), v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17)); + DoCommandP(CMD_CHANGE_SERVICE_INT, STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17)); break; } } @@ -2591,24 +2591,24 @@ enum VehicleCommandTranslation { }; /** Command codes for the shared buttons indexed by VehicleCommandTranslation and vehicle type. */ -static const uint32 _vehicle_command_translation_table[][4] = { +static const StringID _vehicle_msg_translation_table[][4] = { { // VCT_CMD_START_STOP - CMD_START_STOP_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_STOP_START_TRAIN), - CMD_START_STOP_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE), - CMD_START_STOP_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_STOP_START_SHIP), - CMD_START_STOP_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_STOP_START_AIRCRAFT) + STR_ERROR_CAN_T_STOP_START_TRAIN, + STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE, + STR_ERROR_CAN_T_STOP_START_SHIP, + STR_ERROR_CAN_T_STOP_START_AIRCRAFT }, { // VCT_CMD_CLONE_VEH - CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN), - CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_ROAD_VEHICLE), - CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_SHIP), - CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_AIRCRAFT) + STR_ERROR_CAN_T_BUY_TRAIN, + STR_ERROR_CAN_T_BUY_ROAD_VEHICLE, + STR_ERROR_CAN_T_BUY_SHIP, + STR_ERROR_CAN_T_BUY_AIRCRAFT }, { // VCT_CMD_TURN_AROUND - CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN), - CMD_TURN_ROADVEH | CMD_MSG(STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN), - 0xffffffff, // invalid for ships - 0xffffffff // invalid for aircraft + STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN, + STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN, + INVALID_STRING_ID, // invalid for ships + INVALID_STRING_ID // invalid for aircraft }, }; @@ -2619,7 +2619,7 @@ static const uint32 _vehicle_command_translation_table[][4] = { * @param p1 vehicle ID * @param p2 unused */ -void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; @@ -2639,7 +2639,7 @@ void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, ui void StartStopVehicle(const Vehicle *v, bool texteffect) { assert(v->IsPrimaryVehicle()); - DoCommandP(_vehicle_command_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, 0); + DoCommandP(CMD_START_STOP_VEHICLE, _vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, 0); } /** Checks whether the vehicle may be refitted at the moment.*/ @@ -2963,7 +2963,7 @@ public: break; case WID_VV_GOTO_DEPOT: // goto hangar - DoCommandP(GetCmdSendToDepot(v), v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0); + DoCommandP(CMD_SEND_VEHICLE_TO_DEPOT, GetCmdSendToDepotMsg(v), v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0); break; case WID_VV_REFIT: // refit ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID, this); @@ -2987,17 +2987,21 @@ public: * There is no point to it except for starting the vehicle. * For starting the vehicle the player has to open the depot GUI, which is * most likely already open, but is also visible in the vehicle viewport. */ - DoCommandP(_vehicle_command_translation_table[VCT_CMD_CLONE_VEH][v->type], + DoCommandP(CMD_CLONE_VEHICLE, _vehicle_msg_translation_table[VCT_CMD_CLONE_VEH][v->type], _ctrl_pressed ? nullptr : CcCloneVehicle, v->tile, v->index, _ctrl_pressed ? 1 : 0); break; case WID_VV_TURN_AROUND: // turn around assert(v->IsGroundVehicle()); - DoCommandP(_vehicle_command_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0); + if (v->type == VEH_ROAD) { + DoCommandP(CMD_TURN_ROADVEH, _vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0); + } else { + DoCommandP(CMD_REVERSE_TRAIN_DIRECTION, _vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0); + } break; case WID_VV_FORCE_PROCEED: // force proceed assert(v->type == VEH_TRAIN); - DoCommandP(CMD_FORCE_TRAIN_PROCEED | CMD_MSG(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL), v->tile, v->index, 0); + DoCommandP(CMD_FORCE_TRAIN_PROCEED, STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index, 0); break; } } @@ -3006,7 +3010,7 @@ public: { if (str == nullptr) return; - DoCommandP(CMD_RENAME_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type), 0, this->window_number, 0, str); + DoCommandP(CMD_RENAME_VEHICLE, STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, 0, this->window_number, 0, str); } void OnMouseOver(Point pt, int widget) override @@ -3119,7 +3123,7 @@ void StopGlobalFollowVehicle(const Vehicle *v) * @param p2 unused * @param cmd unused */ -void CcBuildPrimaryVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +void CcBuildPrimaryVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) { if (result.Failed()) return; diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp index 8a4772ac08..44e2718b68 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.cpp @@ -138,7 +138,7 @@ public: { if (str == nullptr) return; - DoCommandP(CMD_RENAME_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME), 0, this->window_number, 0, str); + DoCommandP(CMD_RENAME_WAYPOINT, STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME, 0, this->window_number, 0, str); } }; From 5ddfdc8516e35c4f5de2613692d104486151171b Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 3 Oct 2021 22:08:03 +0200 Subject: [PATCH 06/60] Codechange: Declare our custom enum operators as constexpr. --- src/core/enum_type.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/enum_type.hpp b/src/core/enum_type.hpp index d4ea82eff1..72e23ba363 100644 --- a/src/core/enum_type.hpp +++ b/src/core/enum_type.hpp @@ -12,13 +12,13 @@ /** Some enums need to have allowed incrementing (i.e. StationClassID) */ #define DECLARE_POSTFIX_INCREMENT(enum_type) \ - inline enum_type operator ++(enum_type& e, int) \ + inline constexpr enum_type operator ++(enum_type& e, int) \ { \ enum_type e_org = e; \ e = (enum_type)((std::underlying_type::type)e + 1); \ return e_org; \ } \ - inline enum_type operator --(enum_type& e, int) \ + inline constexpr enum_type operator --(enum_type& e, int) \ { \ enum_type e_org = e; \ e = (enum_type)((std::underlying_type::type)e - 1); \ @@ -29,13 +29,13 @@ /** Operators to allow to work with enum as with type safe bit set in C++ */ # define DECLARE_ENUM_AS_BIT_SET(mask_t) \ - inline mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 | m2);} \ - inline mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 & m2);} \ - inline mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 ^ m2);} \ - inline mask_t& operator |= (mask_t& m1, mask_t m2) {m1 = m1 | m2; return m1;} \ - inline mask_t& operator &= (mask_t& m1, mask_t m2) {m1 = m1 & m2; return m1;} \ - inline mask_t& operator ^= (mask_t& m1, mask_t m2) {m1 = m1 ^ m2; return m1;} \ - inline mask_t operator ~(mask_t m) {return (mask_t)(~(std::underlying_type::type)m);} + inline constexpr mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 | m2);} \ + inline constexpr mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 & m2);} \ + inline constexpr mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 ^ m2);} \ + inline constexpr mask_t& operator |= (mask_t& m1, mask_t m2) {m1 = m1 | m2; return m1;} \ + inline constexpr mask_t& operator &= (mask_t& m1, mask_t m2) {m1 = m1 & m2; return m1;} \ + inline constexpr mask_t& operator ^= (mask_t& m1, mask_t m2) {m1 = m1 ^ m2; return m1;} \ + inline constexpr mask_t operator ~(mask_t m) {return (mask_t)(~(std::underlying_type::type)m);} /** From 33ca4f2b9950d98fed902962c847833667ccca9f Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Tue, 5 Oct 2021 22:02:27 +0200 Subject: [PATCH 07/60] Codechange: Let the compile generate the master command table out of templated command traits. This is using a non-intrusive type-traits like templated system, which allows compile-time validation that the command table and the command enum match up. --- src/CMakeLists.txt | 32 ++ src/aircraft_cmd.cpp | 1 + src/aircraft_cmd.h | 19 + src/autoreplace_cmd.cpp | 1 + src/autoreplace_cmd.h | 21 ++ src/command.cpp | 391 +++------------------ src/command_func.h | 4 +- src/command_type.h | 23 +- src/company_cmd.cpp | 1 + src/company_cmd.h | 29 ++ src/depot_cmd.cpp | 1 + src/depot_cmd.h | 19 + src/economy.cpp | 1 + src/economy_cmd.h | 23 ++ src/engine.cpp | 1 + src/engine_cmd.h | 25 ++ src/goal.cpp | 1 + src/goal_cmd.h | 31 ++ src/group_cmd.cpp | 1 + src/group_cmd.h | 33 ++ src/industry_cmd.cpp | 1 + src/industry_cmd.h | 21 ++ src/landscape.cpp | 1 + src/landscape_cmd.h | 21 ++ src/misc_cmd.cpp | 1 + src/misc_cmd.h | 27 ++ src/news_cmd.h | 19 + src/news_gui.cpp | 1 + src/object_cmd.cpp | 1 + src/object_cmd.h | 19 + src/order_backup.cpp | 1 + src/order_cmd.cpp | 1 + src/order_cmd.h | 33 ++ src/rail_cmd.cpp | 1 + src/rail_cmd.h | 37 ++ src/road_cmd.cpp | 1 + src/road_cmd.h | 13 + src/roadveh_cmd.cpp | 1 + src/roadveh_cmd.h | 23 ++ src/settings.cpp | 1 + src/settings_cmd.h | 21 ++ src/ship_cmd.cpp | 1 + src/ship_cmd.h | 19 + src/signs_cmd.cpp | 1 + src/signs_cmd.h | 21 ++ src/station_cmd.cpp | 2 + src/station_cmd.h | 33 ++ src/story.cpp | 1 + src/story_cmd.h | 35 ++ src/subsidy.cpp | 1 + src/subsidy_cmd.h | 19 + src/table/CMakeLists.txt | 2 +- src/table/{train_cmd.h => train_sprites.h} | 2 +- src/terraform_cmd.cpp | 1 + src/terraform_cmd.h | 21 ++ src/timetable_cmd.cpp | 1 + src/timetable_cmd.h | 25 ++ src/town_cmd.cpp | 1 + src/town_cmd.h | 35 ++ src/train_cmd.cpp | 3 +- src/train_cmd.h | 28 ++ src/tree_cmd.cpp | 1 + src/tree_cmd.h | 19 + src/tunnelbridge_cmd.cpp | 1 + src/tunnelbridge_cmd.h | 21 ++ src/vehicle_cmd.cpp | 14 +- src/vehicle_cmd.h | 39 ++ src/viewport.cpp | 1 + src/viewport_cmd.h | 19 + src/water_cmd.cpp | 1 + src/water_cmd.h | 23 ++ src/waypoint_cmd.cpp | 1 + src/waypoint_cmd.h | 25 ++ 73 files changed, 961 insertions(+), 359 deletions(-) create mode 100644 src/aircraft_cmd.h create mode 100644 src/autoreplace_cmd.h create mode 100644 src/company_cmd.h create mode 100644 src/depot_cmd.h create mode 100644 src/economy_cmd.h create mode 100644 src/engine_cmd.h create mode 100644 src/goal_cmd.h create mode 100644 src/group_cmd.h create mode 100644 src/industry_cmd.h create mode 100644 src/landscape_cmd.h create mode 100644 src/misc_cmd.h create mode 100644 src/news_cmd.h create mode 100644 src/object_cmd.h create mode 100644 src/order_cmd.h create mode 100644 src/rail_cmd.h create mode 100644 src/roadveh_cmd.h create mode 100644 src/settings_cmd.h create mode 100644 src/ship_cmd.h create mode 100644 src/signs_cmd.h create mode 100644 src/station_cmd.h create mode 100644 src/story_cmd.h create mode 100644 src/subsidy_cmd.h rename src/table/{train_cmd.h => train_sprites.h} (97%) create mode 100644 src/terraform_cmd.h create mode 100644 src/timetable_cmd.h create mode 100644 src/town_cmd.h create mode 100644 src/train_cmd.h create mode 100644 src/tree_cmd.h create mode 100644 src/tunnelbridge_cmd.h create mode 100644 src/vehicle_cmd.h create mode 100644 src/viewport_cmd.h create mode 100644 src/water_cmd.h create mode 100644 src/waypoint_cmd.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 631eaf6dea..6950e32757 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,6 +38,7 @@ endif() add_files( aircraft.h aircraft_cmd.cpp + aircraft_cmd.h aircraft_gui.cpp airport.cpp airport.h @@ -49,6 +50,7 @@ add_files( autoreplace.cpp autoreplace_base.h autoreplace_cmd.cpp + autoreplace_cmd.h autoreplace_func.h autoreplace_gui.cpp autoreplace_gui.h @@ -90,6 +92,7 @@ add_files( command_type.h company_base.h company_cmd.cpp + company_cmd.h company_func.h company_gui.cpp company_gui.h @@ -119,6 +122,7 @@ add_files( depot.cpp depot_base.h depot_cmd.cpp + depot_cmd.h depot_func.h depot_gui.cpp depot_map.h @@ -132,6 +136,7 @@ add_files( driver.h economy.cpp economy_base.h + economy_cmd.h economy_func.h economy_type.h effectvehicle.cpp @@ -141,6 +146,7 @@ add_files( elrail_func.h engine.cpp engine_base.h + engine_cmd.h engine_func.h engine_gui.cpp engine_gui.h @@ -174,6 +180,7 @@ add_files( gfxinit.h goal.cpp goal_base.h + goal_cmd.h goal_gui.cpp goal_type.h graph_gui.cpp @@ -182,6 +189,7 @@ add_files( ground_vehicle.hpp group.h group_cmd.cpp + group_cmd.h group_gui.cpp group_gui.h group_type.h @@ -198,6 +206,7 @@ add_files( house_type.h industry.h industry_cmd.cpp + industry_cmd.h industry_gui.cpp industry_map.h industry_type.h @@ -208,6 +217,7 @@ add_files( intro_gui.cpp landscape.cpp landscape.h + landscape_cmd.h landscape_type.h language.h livery.h @@ -217,6 +227,7 @@ add_files( map_type.h misc.cpp misc_cmd.cpp + misc_cmd.h misc_gui.cpp mixer.cpp mixer.h @@ -277,6 +288,7 @@ add_files( newgrf_town.h newgrf_townname.cpp newgrf_townname.h + news_cmd.h news_func.h news_gui.cpp news_gui.h @@ -284,6 +296,7 @@ add_files( object.h object_base.h object_cmd.cpp + object_cmd.h object_gui.cpp object_map.h object_type.h @@ -293,6 +306,7 @@ add_files( order_backup.h order_base.h order_cmd.cpp + order_cmd.h order_func.h order_gui.cpp order_type.h @@ -305,6 +319,7 @@ add_files( rail.cpp rail.h rail_cmd.cpp + rail_cmd.h rail_gui.cpp rail_gui.h rail_map.h @@ -327,6 +342,7 @@ add_files( roadstop_base.h roadveh.h roadveh_cmd.cpp + roadveh_cmd.h roadveh_gui.cpp safeguards.h screenshot_gui.cpp @@ -334,6 +350,7 @@ add_files( screenshot.cpp screenshot.h settings.cpp + settings_cmd.h settings_func.h settings_gui.cpp settings_gui.h @@ -343,6 +360,7 @@ add_files( settings_type.h ship.h ship_cmd.cpp + ship_cmd.h ship_gui.cpp signal.cpp signal_func.h @@ -350,6 +368,7 @@ add_files( signs.cpp signs_base.h signs_cmd.cpp + signs_cmd.h signs_func.h signs_gui.cpp signs_type.h @@ -368,6 +387,7 @@ add_files( station.cpp station_base.h station_cmd.cpp + station_cmd.h station_func.h station_gui.cpp station_gui.h @@ -379,6 +399,7 @@ add_files( stdafx.h story.cpp story_base.h + story_cmd.h story_gui.cpp story_type.h strgen/strgen.h @@ -393,11 +414,13 @@ add_files( strings_type.h subsidy.cpp subsidy_base.h + subsidy_cmd.h subsidy_func.h subsidy_gui.cpp subsidy_type.h tar_type.h terraform_cmd.cpp + terraform_cmd.h terraform_gui.cpp terraform_gui.h textbuf.cpp @@ -422,11 +445,13 @@ add_files( tilematrix_type.hpp timetable.h timetable_cmd.cpp + timetable_cmd.h timetable_gui.cpp toolbar_gui.cpp toolbar_gui.h town.h town_cmd.cpp + town_cmd.h town_gui.cpp town_kdtree.h town_map.h @@ -438,22 +463,26 @@ add_files( track_type.h train.h train_cmd.cpp + train_cmd.h train_gui.cpp transparency.h transparency_gui.cpp transparency_gui.h transport_type.h tree_cmd.cpp + tree_cmd.h tree_gui.cpp tree_map.h tunnel_map.cpp tunnel_map.h tunnelbridge.h tunnelbridge_cmd.cpp + tunnelbridge_cmd.h tunnelbridge_map.h vehicle.cpp vehicle_base.h vehicle_cmd.cpp + vehicle_cmd.h vehicle_func.h vehicle_gui.cpp vehicle_gui.h @@ -462,6 +491,7 @@ add_files( vehiclelist.cpp vehiclelist.h viewport.cpp + viewport_cmd.h viewport_func.h viewport_gui.cpp viewport_kdtree.h @@ -472,10 +502,12 @@ add_files( walltime_func.h water.h water_cmd.cpp + water_cmd.h water_map.h waypoint.cpp waypoint_base.h waypoint_cmd.cpp + waypoint_cmd.h waypoint_func.h waypoint_gui.cpp widget.cpp diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 1f52bbecd2..2d9b2ae16a 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -37,6 +37,7 @@ #include "disaster_vehicle.h" #include "newgrf_airporttiles.h" #include "framerate_type.h" +#include "aircraft_cmd.h" #include "table/strings.h" diff --git a/src/aircraft_cmd.h b/src/aircraft_cmd.h new file mode 100644 index 0000000000..769a707c73 --- /dev/null +++ b/src/aircraft_cmd.h @@ -0,0 +1,19 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file aircraft_cmd.h Command definitions related to aircraft. */ + +#ifndef AIRCRAFT_CMD_H +#define AIRCRAFT_CMD_H + +#include "command_type.h" +#include "engine_type.h" +#include "vehicle_type.h" + +CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); + +#endif /* AIRCRAFT_CMD_H */ diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 2602d86ada..db14a4a1d4 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -22,6 +22,7 @@ #include "ai/ai.hpp" #include "news_func.h" #include "strings_func.h" +#include "autoreplace_cmd.h" #include "table/strings.h" diff --git a/src/autoreplace_cmd.h b/src/autoreplace_cmd.h new file mode 100644 index 0000000000..14088d6dc5 --- /dev/null +++ b/src/autoreplace_cmd.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file autoreplace_cmd.h Command definitions related to autoreplace. */ + +#ifndef AUTOREPLACE_CMD_H +#define AUTOREPLACE_CMD_H + +#include "command_type.h" + +CommandProc CmdAutoreplaceVehicle; +CommandProc CmdSetAutoReplace; + +DEF_CMD_TRAIT(CMD_AUTOREPLACE_VEHICLE, CmdAutoreplaceVehicle, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_AUTOREPLACE, CmdSetAutoReplace, 0, CMDT_VEHICLE_MANAGEMENT) + +#endif /* AUTOREPLACE_CMD_H */ diff --git a/src/command.cpp b/src/command.cpp index 449fdece28..b875884f97 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -24,187 +24,66 @@ #include "signal_func.h" #include "core/backup_type.hpp" #include "object_base.h" +#include "autoreplace_cmd.h" +#include "company_cmd.h" +#include "depot_cmd.h" +#include "economy_cmd.h" +#include "engine_cmd.h" +#include "goal_cmd.h" +#include "group_cmd.h" +#include "industry_cmd.h" +#include "landscape_cmd.h" +#include "misc_cmd.h" +#include "news_cmd.h" +#include "object_cmd.h" +#include "order_cmd.h" +#include "rail_cmd.h" +#include "road_cmd.h" +#include "roadveh_cmd.h" +#include "settings_cmd.h" +#include "signs_cmd.h" +#include "station_cmd.h" +#include "story_cmd.h" +#include "subsidy_cmd.h" +#include "terraform_cmd.h" +#include "timetable_cmd.h" +#include "town_cmd.h" +#include "train_cmd.h" +#include "tree_cmd.h" +#include "tunnelbridge_cmd.h" +#include "vehicle_cmd.h" +#include "viewport_cmd.h" +#include "water_cmd.h" +#include "waypoint_cmd.h" + +#include #include "table/strings.h" #include "safeguards.h" -CommandProc CmdBuildRailroadTrack; -CommandProc CmdRemoveRailroadTrack; -CommandProc CmdBuildSingleRail; -CommandProc CmdRemoveSingleRail; -CommandProc CmdLandscapeClear; - -CommandProc CmdBuildBridge; - -CommandProc CmdBuildRailStation; -CommandProc CmdRemoveFromRailStation; -CommandProc CmdConvertRail; - -CommandProc CmdBuildSingleSignal; -CommandProc CmdRemoveSingleSignal; - -CommandProc CmdTerraformLand; - -CommandProc CmdBuildObject; -CommandProc CmdSellLandArea; - -CommandProc CmdBuildTunnel; - -CommandProc CmdBuildTrainDepot; -CommandProc CmdBuildRailWaypoint; -CommandProc CmdRenameWaypoint; -CommandProc CmdRemoveFromRailWaypoint; - -CommandProc CmdBuildRoadStop; -CommandProc CmdRemoveRoadStop; - -CommandProc CmdBuildLongRoad; -CommandProc CmdRemoveLongRoad; -CommandProc CmdBuildRoad; - -CommandProc CmdBuildRoadDepot; - -CommandProc CmdConvertRoad; - -CommandProc CmdBuildAirport; - -CommandProc CmdBuildDock; - -CommandProc CmdBuildShipDepot; - -CommandProc CmdBuildBuoy; - -CommandProc CmdPlantTree; - -CommandProc CmdMoveRailVehicle; - -CommandProc CmdBuildVehicle; -CommandProc CmdSellVehicle; -CommandProc CmdRefitVehicle; -CommandProc CmdSendVehicleToDepot; -CommandProc CmdSetVehicleVisibility; - -CommandProc CmdForceTrainProceed; -CommandProc CmdReverseTrainDirection; - -CommandProc CmdClearOrderBackup; -CommandProc CmdModifyOrder; -CommandProc CmdSkipToOrder; -CommandProc CmdDeleteOrder; -CommandProc CmdInsertOrder; -CommandProc CmdChangeServiceInt; - -CommandProc CmdBuildIndustry; -CommandProc CmdIndustryCtrl; - -CommandProc CmdSetCompanyManagerFace; -CommandProc CmdSetCompanyColour; - -CommandProc CmdIncreaseLoan; -CommandProc CmdDecreaseLoan; - -CommandProc CmdWantEnginePreview; -CommandProc CmdEngineCtrl; - -CommandProc CmdRenameVehicle; -CommandProc CmdRenameEngine; - -CommandProc CmdRenameCompany; -CommandProc CmdRenamePresident; - -CommandProc CmdRenameStation; -CommandProc CmdRenameDepot; - -CommandProc CmdPlaceSign; -CommandProc CmdRenameSign; - -CommandProc CmdTurnRoadVeh; - -CommandProc CmdPause; - -CommandProc CmdBuyShareInCompany; -CommandProc CmdSellShareInCompany; -CommandProc CmdBuyCompany; - -CommandProc CmdFoundTown; -CommandProc CmdRenameTown; -CommandProc CmdDoTownAction; -CommandProc CmdTownGrowthRate; -CommandProc CmdTownRating; -CommandProc CmdTownCargoGoal; -CommandProc CmdTownSetText; -CommandProc CmdExpandTown; -CommandProc CmdDeleteTown; - -CommandProc CmdChangeSetting; -CommandProc CmdChangeCompanySetting; - -CommandProc CmdOrderRefit; -CommandProc CmdCloneOrder; - -CommandProc CmdClearArea; +/** + * Define a command with the flags which belongs to it. + * + * This struct connects a command handler function with the flags created with + * the #CMD_AUTO, #CMD_OFFLINE and #CMD_SERVER values. + */ +struct CommandInfo { + CommandProc *proc; ///< The procedure to actually executing + const char *name; ///< A human readable name for the procedure + CommandFlags flags; ///< The (command) flags to that apply to this command + CommandType type; ///< The type of command. +}; +/* Helpers to generate the master command table from the command traits. */ -CommandProc CmdGiveMoney; -CommandProc CmdMoneyCheat; -CommandProc CmdChangeBankBalance; -CommandProc CmdBuildCanal; -CommandProc CmdBuildLock; +template +inline constexpr CommandInfo CommandFromTrait() noexcept { return { T::proc, T::name, T::flags, T::type }; }; -CommandProc CmdCreateSubsidy; -CommandProc CmdCompanyCtrl; -CommandProc CmdCustomNewsItem; -CommandProc CmdCreateGoal; -CommandProc CmdRemoveGoal; -CommandProc CmdSetGoalText; -CommandProc CmdSetGoalProgress; -CommandProc CmdSetGoalCompleted; -CommandProc CmdGoalQuestion; -CommandProc CmdGoalQuestionAnswer; -CommandProc CmdCreateStoryPage; -CommandProc CmdCreateStoryPageElement; -CommandProc CmdUpdateStoryPageElement; -CommandProc CmdSetStoryPageTitle; -CommandProc CmdSetStoryPageDate; -CommandProc CmdShowStoryPage; -CommandProc CmdRemoveStoryPage; -CommandProc CmdRemoveStoryPageElement; -CommandProc CmdScrollViewport; -CommandProc CmdStoryPageButton; - -CommandProc CmdLevelLand; - -CommandProc CmdBuildSignalTrack; -CommandProc CmdRemoveSignalTrack; - -CommandProc CmdSetAutoReplace; - -CommandProc CmdCloneVehicle; -CommandProc CmdStartStopVehicle; -CommandProc CmdMassStartStopVehicle; -CommandProc CmdAutoreplaceVehicle; -CommandProc CmdDepotSellAllVehicles; -CommandProc CmdDepotMassAutoReplace; - -CommandProc CmdCreateGroup; -CommandProc CmdAlterGroup; -CommandProc CmdDeleteGroup; -CommandProc CmdAddVehicleGroup; -CommandProc CmdAddSharedVehicleGroup; -CommandProc CmdRemoveAllVehiclesGroup; -CommandProc CmdSetGroupFlag; -CommandProc CmdSetGroupLivery; - -CommandProc CmdMoveOrder; -CommandProc CmdChangeTimetable; -CommandProc CmdSetVehicleOnTime; -CommandProc CmdAutofillTimetable; -CommandProc CmdSetTimetableStart; - -CommandProc CmdOpenCloseAirport; - -#define DEF_CMD(proc, flags, type) {proc, #proc, (CommandFlags)flags, type} +template +inline constexpr auto MakeCommandsFromTraits(std::integer_sequence) noexcept { + return std::array{{ CommandFromTrait(i)>>()... }}; +} /** * The master command table @@ -213,162 +92,8 @@ CommandProc CmdOpenCloseAirport; * the flags which belongs to it. The indices are the same * as the value from the CMD_* enums. */ -static const Command _command_proc_table[] = { - DEF_CMD(CmdBuildRailroadTrack, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_RAILROAD_TRACK - DEF_CMD(CmdRemoveRailroadTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_RAILROAD_TRACK - DEF_CMD(CmdBuildSingleRail, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SINGLE_RAIL - DEF_CMD(CmdRemoveSingleRail, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SINGLE_RAIL - DEF_CMD(CmdLandscapeClear, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_LANDSCAPE_CLEAR - DEF_CMD(CmdBuildBridge, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_BRIDGE - DEF_CMD(CmdBuildRailStation, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_RAIL_STATION - DEF_CMD(CmdBuildTrainDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_TRAIN_DEPOT - DEF_CMD(CmdBuildSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SIGNALS - DEF_CMD(CmdRemoveSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SIGNALS - DEF_CMD(CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_TERRAFORM_LAND - DEF_CMD(CmdBuildObject, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT - DEF_CMD(CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_TUNNEL - DEF_CMD(CmdRemoveFromRailStation, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_FROM_RAIL_STATION - DEF_CMD(CmdConvertRail, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CONVERT_RAILD - DEF_CMD(CmdBuildRailWaypoint, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_RAIL_WAYPOINT - DEF_CMD(CmdRenameWaypoint, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_WAYPOINT - DEF_CMD(CmdRemoveFromRailWaypoint, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_FROM_RAIL_WAYPOINT - - DEF_CMD(CmdBuildRoadStop, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD_STOP - DEF_CMD(CmdRemoveRoadStop, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_ROAD_STOP - DEF_CMD(CmdBuildLongRoad,CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_LONG_ROAD - DEF_CMD(CmdRemoveLongRoad, CMD_NO_TEST | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_LONG_ROAD; towns may disallow removing road bits (as they are connected) in test, but in exec they're removed and thus removing is allowed. - DEF_CMD(CmdBuildRoad, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD - DEF_CMD(CmdBuildRoadDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD_DEPOT - DEF_CMD(CmdConvertRoad, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CONVERT_ROAD - - DEF_CMD(CmdBuildAirport, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_AIRPORT - DEF_CMD(CmdBuildDock, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_DOCK - DEF_CMD(CmdBuildShipDepot, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SHIP_DEPOT - DEF_CMD(CmdBuildBuoy, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_BUOY - DEF_CMD(CmdPlantTree, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_PLANT_TREE - - DEF_CMD(CmdBuildVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION ), // CMD_BUILD_VEHICLE - DEF_CMD(CmdSellVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION ), // CMD_SELL_VEHICLE - DEF_CMD(CmdRefitVehicle, 0, CMDT_VEHICLE_CONSTRUCTION ), // CMD_REFIT_VEHICLE - DEF_CMD(CmdSendVehicleToDepot, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_SEND_VEHICLE_TO_DEPOT - DEF_CMD(CmdSetVehicleVisibility, 0, CMDT_COMPANY_SETTING ), // CMD_SET_VEHICLE_VISIBILITY - - DEF_CMD(CmdMoveRailVehicle, 0, CMDT_VEHICLE_CONSTRUCTION ), // CMD_MOVE_RAIL_VEHICLE - DEF_CMD(CmdForceTrainProceed, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_FORCE_TRAIN_PROCEED - DEF_CMD(CmdReverseTrainDirection, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_REVERSE_TRAIN_DIRECTION - - DEF_CMD(CmdClearOrderBackup, CMD_CLIENT_ID, CMDT_SERVER_SETTING ), // CMD_CLEAR_ORDER_BACKUP - DEF_CMD(CmdModifyOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_MODIFY_ORDER - DEF_CMD(CmdSkipToOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SKIP_TO_ORDER - DEF_CMD(CmdDeleteOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_DELETE_ORDER - DEF_CMD(CmdInsertOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_INSERT_ORDER - - DEF_CMD(CmdChangeServiceInt, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_CHANGE_SERVICE_INT - - DEF_CMD(CmdBuildIndustry, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_INDUSTRY - DEF_CMD(CmdIndustryCtrl, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_INDUSTRY_CTRL - - DEF_CMD(CmdSetCompanyManagerFace, 0, CMDT_OTHER_MANAGEMENT ), // CMD_SET_COMPANY_MANAGER_FACE - DEF_CMD(CmdSetCompanyColour, 0, CMDT_OTHER_MANAGEMENT ), // CMD_SET_COMPANY_COLOUR - - DEF_CMD(CmdIncreaseLoan, 0, CMDT_MONEY_MANAGEMENT ), // CMD_INCREASE_LOAN - DEF_CMD(CmdDecreaseLoan, 0, CMDT_MONEY_MANAGEMENT ), // CMD_DECREASE_LOAN - - DEF_CMD(CmdWantEnginePreview, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_WANT_ENGINE_PREVIEW - DEF_CMD(CmdEngineCtrl, CMD_DEITY, CMDT_VEHICLE_MANAGEMENT ), // CMD_ENGINE_CTRL - - DEF_CMD(CmdRenameVehicle, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_VEHICLE - DEF_CMD(CmdRenameEngine, CMD_SERVER, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_ENGINE - - DEF_CMD(CmdRenameCompany, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_COMPANY - DEF_CMD(CmdRenamePresident, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_PRESIDENT - - DEF_CMD(CmdRenameStation, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_STATION - DEF_CMD(CmdRenameDepot, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_DEPOT - - DEF_CMD(CmdPlaceSign, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_PLACE_SIGN - DEF_CMD(CmdRenameSign, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_SIGN - - DEF_CMD(CmdTurnRoadVeh, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_TURN_ROADVEH - - DEF_CMD(CmdPause, CMD_SERVER | CMD_NO_EST, CMDT_SERVER_SETTING ), // CMD_PAUSE - - DEF_CMD(CmdBuyShareInCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_BUY_SHARE_IN_COMPANY - DEF_CMD(CmdSellShareInCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_SELL_SHARE_IN_COMPANY - DEF_CMD(CmdBuyCompany, 0, CMDT_MONEY_MANAGEMENT ), // CMD_BUY_COMANY - - DEF_CMD(CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_FOUND_TOWN; founding random town can fail only in exec run - DEF_CMD(CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_TOWN - DEF_CMD(CmdDoTownAction, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_DO_TOWN_ACTION - DEF_CMD(CmdTownCargoGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_CARGO_GOAL - DEF_CMD(CmdTownGrowthRate, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_GROWTH_RATE - DEF_CMD(CmdTownRating, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_RATING - DEF_CMD(CmdTownSetText, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_SET_TEXT - DEF_CMD(CmdExpandTown, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_EXPAND_TOWN - DEF_CMD(CmdDeleteTown, CMD_OFFLINE, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_DELETE_TOWN - - DEF_CMD(CmdOrderRefit, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_ORDER_REFIT - DEF_CMD(CmdCloneOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_CLONE_ORDER - - DEF_CMD(CmdClearArea, CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CLEAR_AREA; destroying multi-tile houses makes town rating differ between test and execution - - DEF_CMD(CmdMoneyCheat, CMD_OFFLINE, CMDT_CHEAT ), // CMD_MONEY_CHEAT - DEF_CMD(CmdChangeBankBalance, CMD_DEITY, CMDT_MONEY_MANAGEMENT ), // CMD_CHANGE_BANK_BALANCE - DEF_CMD(CmdBuildCanal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_CANAL - DEF_CMD(CmdCreateSubsidy, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_SUBSIDY - DEF_CMD(CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID | CMD_NO_EST, CMDT_SERVER_SETTING ), // CMD_COMPANY_CTRL - DEF_CMD(CmdCustomNewsItem, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_CUSTOM_NEWS_ITEM - DEF_CMD(CmdCreateGoal, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_GOAL - DEF_CMD(CmdRemoveGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_REMOVE_GOAL - DEF_CMD(CmdSetGoalText, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_TEXT - DEF_CMD(CmdSetGoalProgress, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_PROGRESS - DEF_CMD(CmdSetGoalCompleted, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_SET_GOAL_COMPLETED - DEF_CMD(CmdGoalQuestion, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_GOAL_QUESTION - DEF_CMD(CmdGoalQuestionAnswer, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_GOAL_QUESTION_ANSWER - DEF_CMD(CmdCreateStoryPage, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_STORY_PAGE - DEF_CMD(CmdCreateStoryPageElement, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_CREATE_STORY_PAGE_ELEMENT - DEF_CMD(CmdUpdateStoryPageElement, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_UPDATE_STORY_PAGE_ELEMENT - DEF_CMD(CmdSetStoryPageTitle, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_SET_STORY_PAGE_TITLE - DEF_CMD(CmdSetStoryPageDate, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_SET_STORY_PAGE_DATE - DEF_CMD(CmdShowStoryPage, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_SHOW_STORY_PAGE - DEF_CMD(CmdRemoveStoryPage, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_REMOVE_STORY_PAGE - DEF_CMD(CmdRemoveStoryPageElement, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_REMOVE_STORY_ELEMENT_PAGE - DEF_CMD(CmdScrollViewport, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_SCROLL_VIEWPORT - DEF_CMD(CmdStoryPageButton, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_STORY_PAGE_BUTTON - - DEF_CMD(CmdLevelLand, CMD_ALL_TILES | CMD_NO_TEST | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_LEVEL_LAND; test run might clear tiles multiple times, in execution that only happens once - - DEF_CMD(CmdBuildLock, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_LOCK - - DEF_CMD(CmdBuildSignalTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SIGNAL_TRACK - DEF_CMD(CmdRemoveSignalTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SIGNAL_TRACK - - DEF_CMD(CmdGiveMoney, 0, CMDT_MONEY_MANAGEMENT ), // CMD_GIVE_MONEY - DEF_CMD(CmdChangeSetting, CMD_SERVER, CMDT_SERVER_SETTING ), // CMD_CHANGE_SETTING - DEF_CMD(CmdChangeCompanySetting, 0, CMDT_COMPANY_SETTING ), // CMD_CHANGE_COMPANY_SETTING - DEF_CMD(CmdSetAutoReplace, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_SET_AUTOREPLACE - DEF_CMD(CmdCloneVehicle, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION ), // CMD_CLONE_VEHICLE; NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost - DEF_CMD(CmdStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_START_STOP_VEHICLE - DEF_CMD(CmdMassStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_MASS_START_STOP - DEF_CMD(CmdAutoreplaceVehicle, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_AUTOREPLACE_VEHICLE - DEF_CMD(CmdDepotSellAllVehicles, 0, CMDT_VEHICLE_CONSTRUCTION ), // CMD_DEPOT_SELL_ALL_VEHICLES - DEF_CMD(CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION ), // CMD_DEPOT_MASS_AUTOREPLACE - DEF_CMD(CmdCreateGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_CREATE_GROUP - DEF_CMD(CmdDeleteGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_DELETE_GROUP - DEF_CMD(CmdAlterGroup, 0, CMDT_OTHER_MANAGEMENT ), // CMD_ALTER_GROUP - DEF_CMD(CmdAddVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_ADD_VEHICLE_GROUP - DEF_CMD(CmdAddSharedVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_ADD_SHARE_VEHICLE_GROUP - DEF_CMD(CmdRemoveAllVehiclesGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_REMOVE_ALL_VEHICLES_GROUP - DEF_CMD(CmdSetGroupFlag, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_GROUP_FLAG - DEF_CMD(CmdSetGroupLivery, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_GROUP_LIVERY - DEF_CMD(CmdMoveOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_MOVE_ORDER - DEF_CMD(CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_CHANGE_TIMETABLE - DEF_CMD(CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_VEHICLE_ON_TIME - DEF_CMD(CmdAutofillTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_AUTOFILL_TIMETABLE - DEF_CMD(CmdSetTimetableStart, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_TIMETABLE_START - - DEF_CMD(CmdOpenCloseAirport, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_OPEN_CLOSE_AIRPORT -}; +static constexpr auto _command_proc_table = MakeCommandsFromTraits(std::make_integer_sequence, CMD_END>{}); + /*! * This function range-checks a cmd, and checks if the cmd is not nullptr @@ -376,9 +101,9 @@ static const Command _command_proc_table[] = { * @param cmd The integer value of a command * @return true if the command is valid (and got a CommandProc function) */ -bool IsValidCommand(uint32 cmd) +bool IsValidCommand(Commands cmd) { - return cmd < lengthof(_command_proc_table) && _command_proc_table[cmd].proc != nullptr; + return cmd < _command_proc_table.size() && _command_proc_table[cmd].proc != nullptr; } /*! @@ -414,7 +139,7 @@ const char *GetCommandName(Commands cmd) * @param cmd The command to check. * @return True if the command is allowed while paused, false otherwise. */ -bool IsCommandAllowedWhilePaused(uint32 cmd) +bool IsCommandAllowedWhilePaused(Commands cmd) { /* Lookup table for the command types that are allowed for a given pause level setting. */ static const int command_type_lookup[] = { @@ -704,7 +429,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba _additional_cash_required = 0; /* Get pointer to command handler */ - assert(cmd < lengthof(_command_proc_table)); + assert(cmd < _command_proc_table.size()); CommandProc *proc = _command_proc_table[cmd].proc; /* Shouldn't happen, but you never know when someone adds * NULLs to the _command_proc_table. */ diff --git a/src/command_func.h b/src/command_func.h index 662ae00a5c..15c88ea034 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -47,11 +47,11 @@ void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *cal extern Money _additional_cash_required; -bool IsValidCommand(uint32 cmd); +bool IsValidCommand(Commands cmd); CommandFlags GetCommandFlags(Commands cmd); const char *GetCommandName(Commands cmd); Money GetAvailableMoneyForCommand(); -bool IsCommandAllowedWhilePaused(uint32 cmd); +bool IsCommandAllowedWhilePaused(Commands cmd); /** * Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags diff --git a/src/command_type.h b/src/command_type.h index 972db596ea..ecb24df125 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -423,18 +423,17 @@ enum CommandPauseLevel { */ typedef CommandCost CommandProc(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text); -/** - * Define a command with the flags which belongs to it. - * - * This struct connect a command handler function with the flags created with - * the #CMD_AUTO, #CMD_OFFLINE and #CMD_SERVER values. - */ -struct Command { - CommandProc *proc; ///< The procedure to actually executing - const char *name; ///< A human readable name for the procedure - CommandFlags flags; ///< The (command) flags to that apply to this command - CommandType type; ///< The type of command. -}; + +/** Defines the traits of a command. */ +template struct CommandTraits; + +#define DEF_CMD_TRAIT(cmd_, proc_, flags_, type_) \ + template<> struct CommandTraits { \ + static constexpr auto &proc = proc_; \ + static constexpr CommandFlags flags = (CommandFlags)(flags_); \ + static constexpr CommandType type = type_; \ + static inline constexpr const char *name = #proc_; \ + }; /** * Define a callback function for the client, after the command is finished. diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 792dd624b2..f18fe343ad 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -36,6 +36,7 @@ #include "goal_base.h" #include "story_base.h" #include "widgets/statusbar_widget.h" +#include "company_cmd.h" #include "table/strings.h" diff --git a/src/company_cmd.h b/src/company_cmd.h new file mode 100644 index 0000000000..0d3e2d2fd6 --- /dev/null +++ b/src/company_cmd.h @@ -0,0 +1,29 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file company_cmd.h Command definitions related to companies. */ + +#ifndef COMPANY_CMD_H +#define COMPANY_CMD_H + +#include "command_type.h" + +CommandProc CmdCompanyCtrl; +CommandProc CmdGiveMoney; +CommandProc CmdRenameCompany; +CommandProc CmdRenamePresident; +CommandProc CmdSetCompanyManagerFace; +CommandProc CmdSetCompanyColour; + +DEF_CMD_TRAIT(CMD_COMPANY_CTRL, CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID | CMD_NO_EST, CMDT_SERVER_SETTING) +DEF_CMD_TRAIT(CMD_GIVE_MONEY, CmdGiveMoney, 0, CMDT_MONEY_MANAGEMENT) +DEF_CMD_TRAIT(CMD_RENAME_COMPANY, CmdRenameCompany, 0, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_RENAME_PRESIDENT, CmdRenamePresident, 0, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_COMPANY_MANAGER_FACE, CmdSetCompanyManagerFace, 0, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_COMPANY_COLOUR, CmdSetCompanyColour, 0, CMDT_OTHER_MANAGEMENT) + +#endif /* COMPANY_CMD_H */ diff --git a/src/depot_cmd.cpp b/src/depot_cmd.cpp index 6f5ddda27e..e49936f552 100644 --- a/src/depot_cmd.cpp +++ b/src/depot_cmd.cpp @@ -16,6 +16,7 @@ #include "vehicle_gui.h" #include "vehiclelist.h" #include "window_func.h" +#include "depot_cmd.h" #include "table/strings.h" diff --git a/src/depot_cmd.h b/src/depot_cmd.h new file mode 100644 index 0000000000..9c39db1e2e --- /dev/null +++ b/src/depot_cmd.h @@ -0,0 +1,19 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file depot_cmd.h Command definitions related to depots. */ + +#ifndef DEPOT_CMD_H +#define DEPOT_CMD_H + +#include "command_type.h" + +CommandProc CmdRenameDepot; + +DEF_CMD_TRAIT(CMD_RENAME_DEPOT, CmdRenameDepot, 0, CMDT_OTHER_MANAGEMENT) + +#endif /* DEPOT_CMD_H */ diff --git a/src/economy.cpp b/src/economy.cpp index 3beeb25f58..329a0a5a81 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -48,6 +48,7 @@ #include "goal_base.h" #include "story_base.h" #include "linkgraph/refresh.h" +#include "economy_cmd.h" #include "table/strings.h" #include "table/pricebase.h" diff --git a/src/economy_cmd.h b/src/economy_cmd.h new file mode 100644 index 0000000000..f182af81f2 --- /dev/null +++ b/src/economy_cmd.h @@ -0,0 +1,23 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file economy_cmd.h Command definitions related to the economy. */ + +#ifndef ECONOMY_CMD_H +#define ECONOMY_CMD_H + +#include "command_type.h" + +CommandProc CmdBuyShareInCompany; +CommandProc CmdSellShareInCompany; +CommandProc CmdBuyCompany; + +DEF_CMD_TRAIT(CMD_BUY_SHARE_IN_COMPANY, CmdBuyShareInCompany, 0, CMDT_MONEY_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SELL_SHARE_IN_COMPANY, CmdSellShareInCompany, 0, CMDT_MONEY_MANAGEMENT) +DEF_CMD_TRAIT(CMD_BUY_COMPANY, CmdBuyCompany, 0, CMDT_MONEY_MANAGEMENT) + +#endif /* ECONOMY_CMD_H */ diff --git a/src/engine.cpp b/src/engine.cpp index f330cf6048..56f81ffce9 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -29,6 +29,7 @@ #include "vehicle_func.h" #include "articulated_vehicles.h" #include "error.h" +#include "engine_base.h" #include "table/strings.h" #include "table/engines.h" diff --git a/src/engine_cmd.h b/src/engine_cmd.h new file mode 100644 index 0000000000..3ed47e8051 --- /dev/null +++ b/src/engine_cmd.h @@ -0,0 +1,25 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file engine_cmd.h Command definitions related to engines. */ + +#ifndef ENGINE_CMD_H +#define ENGINE_CMD_H + +#include "command_type.h" + +CommandProc CmdWantEnginePreview; +CommandProc CmdEngineCtrl; +CommandProc CmdRenameEngine; +CommandProc CmdSetVehicleVisibility; + +DEF_CMD_TRAIT(CMD_WANT_ENGINE_PREVIEW, CmdWantEnginePreview, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_ENGINE_CTRL, CmdEngineCtrl, CMD_DEITY, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_RENAME_ENGINE, CmdRenameEngine, CMD_SERVER, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_VEHICLE_VISIBILITY, CmdSetVehicleVisibility, 0, CMDT_COMPANY_SETTING) + +#endif /* ENGINE_CMD_H */ diff --git a/src/goal.cpp b/src/goal.cpp index c611650597..7c24386d18 100644 --- a/src/goal.cpp +++ b/src/goal.cpp @@ -23,6 +23,7 @@ #include "network/network.h" #include "network/network_base.h" #include "network/network_func.h" +#include "goal_cmd.h" #include "safeguards.h" diff --git a/src/goal_cmd.h b/src/goal_cmd.h new file mode 100644 index 0000000000..3b047f11ac --- /dev/null +++ b/src/goal_cmd.h @@ -0,0 +1,31 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file goal_cmd.h Command definitions related to goals. */ + +#ifndef GOAL_CMD_H +#define GOAL_CMD_H + +#include "command_type.h" + +CommandProc CmdCreateGoal; +CommandProc CmdRemoveGoal; +CommandProc CmdSetGoalText; +CommandProc CmdSetGoalProgress; +CommandProc CmdSetGoalCompleted; +CommandProc CmdGoalQuestion; +CommandProc CmdGoalQuestionAnswer; + +DEF_CMD_TRAIT(CMD_CREATE_GOAL, CmdCreateGoal, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_REMOVE_GOAL, CmdRemoveGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_GOAL_TEXT, CmdSetGoalText, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_GOAL_PROGRESS, CmdSetGoalProgress, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_GOAL_COMPLETED, CmdSetGoalCompleted, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_GOAL_QUESTION, CmdGoalQuestion, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_GOAL_QUESTION_ANSWER, CmdGoalQuestionAnswer, CMD_DEITY, CMDT_OTHER_MANAGEMENT) + +#endif /* GOAL_CMD_H */ diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index ec4358f765..8b67fbeae8 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -19,6 +19,7 @@ #include "company_func.h" #include "core/pool_func.hpp" #include "order_backup.h" +#include "group_cmd.h" #include "table/strings.h" diff --git a/src/group_cmd.h b/src/group_cmd.h new file mode 100644 index 0000000000..a58a6f8aa5 --- /dev/null +++ b/src/group_cmd.h @@ -0,0 +1,33 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file group_cmd.h Command definitions related to engine groups. */ + +#ifndef GROUP_CMD_H +#define GROUP_CMD_H + +#include "command_type.h" + +CommandProc CmdCreateGroup; +CommandProc CmdAlterGroup; +CommandProc CmdDeleteGroup; +CommandProc CmdAddVehicleGroup; +CommandProc CmdAddSharedVehicleGroup; +CommandProc CmdRemoveAllVehiclesGroup; +CommandProc CmdSetGroupFlag; +CommandProc CmdSetGroupLivery; + +DEF_CMD_TRAIT(CMD_CREATE_GROUP, CmdCreateGroup, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_DELETE_GROUP, CmdDeleteGroup, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_ALTER_GROUP, CmdAlterGroup, 0, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_ADD_VEHICLE_GROUP, CmdAddVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_ADD_SHARED_VEHICLE_GROUP, CmdAddSharedVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_REMOVE_ALL_VEHICLES_GROUP, CmdRemoveAllVehiclesGroup, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_GROUP_FLAG, CmdSetGroupFlag, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_GROUP_LIVERY, CmdSetGroupLivery, 0, CMDT_ROUTE_MANAGEMENT) + +#endif /* GROUP_CMD_H */ diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 529e01edbe..a24f35f756 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -42,6 +42,7 @@ #include "error.h" #include "cmd_helper.h" #include "string_func.h" +#include "industry_cmd.h" #include "table/strings.h" #include "table/industry_land.h" diff --git a/src/industry_cmd.h b/src/industry_cmd.h new file mode 100644 index 0000000000..e1f18932a9 --- /dev/null +++ b/src/industry_cmd.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file industry_cmd.h Command definitions related to industries. */ + +#ifndef INDUSTRY_CMD_H +#define INDUSTRY_CMD_H + +#include "command_type.h" + +CommandProc CmdBuildIndustry; +CommandProc CmdIndustryCtrl; + +DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_INDUSTRY_CTRL, CmdIndustryCtrl, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) + +#endif /* INDUSTRY_CMD_H */ diff --git a/src/landscape.cpp b/src/landscape.cpp index 242ee089ac..1cc3b1ad20 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -31,6 +31,7 @@ #include "pathfinder/npf/aystar.h" #include "saveload/saveload.h" #include "framerate_type.h" +#include "landscape_cmd.h" #include #include #include diff --git a/src/landscape_cmd.h b/src/landscape_cmd.h new file mode 100644 index 0000000000..f3b6fd3fca --- /dev/null +++ b/src/landscape_cmd.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file landscape_cmd.h Command definitions related to landscape (slopes etc.). */ + +#ifndef LANDSCAPE_CMD_H +#define LANDSCAPE_CMD_H + +#include "command_type.h" + +CommandProc CmdLandscapeClear; +CommandProc CmdClearArea; + +DEF_CMD_TRAIT(CMD_LANDSCAPE_CLEAR, CmdLandscapeClear, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_CLEAR_AREA, CmdClearArea, CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // destroying multi-tile houses makes town rating differ between test and execution + +#endif /* LANDSCAPE_CMD_H */ diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index c461d36dc8..2e70f5fdd3 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -22,6 +22,7 @@ #include "tile_map.h" #include "texteff.hpp" #include "core/backup_type.hpp" +#include "misc_cmd.h" #include "table/strings.h" diff --git a/src/misc_cmd.h b/src/misc_cmd.h new file mode 100644 index 0000000000..6827db3ac2 --- /dev/null +++ b/src/misc_cmd.h @@ -0,0 +1,27 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file misc_cmd.h Miscellaneous command definitions. */ + +#ifndef MISC_CMD_H +#define MISC_CMD_H + +#include "command_type.h" + +CommandProc CmdMoneyCheat; +CommandProc CmdChangeBankBalance; +CommandProc CmdIncreaseLoan; +CommandProc CmdDecreaseLoan; +CommandProc CmdPause; + +DEF_CMD_TRAIT(CMD_MONEY_CHEAT, CmdMoneyCheat, CMD_OFFLINE, CMDT_CHEAT) +DEF_CMD_TRAIT(CMD_CHANGE_BANK_BALANCE, CmdChangeBankBalance, CMD_DEITY, CMDT_MONEY_MANAGEMENT) +DEF_CMD_TRAIT(CMD_INCREASE_LOAN, CmdIncreaseLoan, 0, CMDT_MONEY_MANAGEMENT) +DEF_CMD_TRAIT(CMD_DECREASE_LOAN, CmdDecreaseLoan, 0, CMDT_MONEY_MANAGEMENT) +DEF_CMD_TRAIT(CMD_PAUSE, CmdPause, CMD_SERVER | CMD_NO_EST, CMDT_SERVER_SETTING) + +#endif /* MISC_CMD_H */ diff --git a/src/news_cmd.h b/src/news_cmd.h new file mode 100644 index 0000000000..4a75037b3b --- /dev/null +++ b/src/news_cmd.h @@ -0,0 +1,19 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file news_cmd.h Command definitions related to news messages. */ + +#ifndef NEWS_CMD_H +#define NEWS_CMD_H + +#include "command_type.h" + +CommandProc CmdCustomNewsItem; + +DEF_CMD_TRAIT(CMD_CUSTOM_NEWS_ITEM, CmdCustomNewsItem, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT) + +#endif /* NEWS_CMD_H */ diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 10a49b62e8..3f3b918671 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -35,6 +35,7 @@ #include "guitimer_func.h" #include "group_gui.h" #include "zoom_func.h" +#include "news_cmd.h" #include "widgets/news_widget.h" diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 328cadd93d..f207d47867 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -33,6 +33,7 @@ #include "newgrf_debug.h" #include "vehicle_func.h" #include "station_func.h" +#include "object_cmd.h" #include "table/strings.h" #include "table/object_land.h" diff --git a/src/object_cmd.h b/src/object_cmd.h new file mode 100644 index 0000000000..b7119afc38 --- /dev/null +++ b/src/object_cmd.h @@ -0,0 +1,19 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file object_cmd.h Command definitions related to objects. */ + +#ifndef OBJECT_CMD_H +#define OBJECT_CMD_H + +#include "command_type.h" + +CommandProc CmdBuildObject; + +DEF_CMD_TRAIT(CMD_BUILD_OBJECT, CmdBuildObject, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) + +#endif /* OBJECT_CMD_H */ diff --git a/src/order_backup.cpp b/src/order_backup.cpp index cba46941c5..51e1b67ff0 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -16,6 +16,7 @@ #include "vehicle_base.h" #include "window_func.h" #include "station_map.h" +#include "order_cmd.h" #include "safeguards.h" diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index b681b63796..2f366b6743 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -26,6 +26,7 @@ #include "company_base.h" #include "order_backup.h" #include "cheat_type.h" +#include "order_cmd.h" #include "table/strings.h" diff --git a/src/order_cmd.h b/src/order_cmd.h new file mode 100644 index 0000000000..606cbef605 --- /dev/null +++ b/src/order_cmd.h @@ -0,0 +1,33 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file order_cmd.h Command definitions related to orders. */ + +#ifndef ORDER_CMD_H +#define ORDER_CMD_H + +#include "command_type.h" + +CommandProc CmdModifyOrder; +CommandProc CmdSkipToOrder; +CommandProc CmdDeleteOrder; +CommandProc CmdInsertOrder; +CommandProc CmdOrderRefit; +CommandProc CmdCloneOrder; +CommandProc CmdMoveOrder; +CommandProc CmdClearOrderBackup; + +DEF_CMD_TRAIT(CMD_MODIFY_ORDER, CmdModifyOrder, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SKIP_TO_ORDER, CmdSkipToOrder, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_DELETE_ORDER, CmdDeleteOrder, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_INSERT_ORDER, CmdInsertOrder, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_ORDER_REFIT, CmdOrderRefit, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CLONE_ORDER, CmdCloneOrder, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_MOVE_ORDER, CmdMoveOrder, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CLEAR_ORDER_BACKUP, CmdClearOrderBackup, CMD_CLIENT_ID, CMDT_SERVER_SETTING) + +#endif /* ORDER_CMD_H */ diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 8ff8d64539..449254f516 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -31,6 +31,7 @@ #include "strings_func.h" #include "company_gui.h" #include "object_map.h" +#include "rail_cmd.h" #include "table/strings.h" #include "table/railtypes.h" diff --git a/src/rail_cmd.h b/src/rail_cmd.h new file mode 100644 index 0000000000..e625eb03db --- /dev/null +++ b/src/rail_cmd.h @@ -0,0 +1,37 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file rail_cmd.h Command definitions for rail. */ + +#ifndef RAIL_CMD_H +#define RAIL_CMD_H + +#include "command_type.h" + +CommandProc CmdBuildRailroadTrack; +CommandProc CmdRemoveRailroadTrack; +CommandProc CmdBuildSingleRail; +CommandProc CmdRemoveSingleRail; +CommandProc CmdBuildTrainDepot; +CommandProc CmdBuildSingleSignal; +CommandProc CmdRemoveSingleSignal; +CommandProc CmdConvertRail; +CommandProc CmdBuildSignalTrack; +CommandProc CmdRemoveSignalTrack; + +DEF_CMD_TRAIT(CMD_BUILD_RAILROAD_TRACK, CmdBuildRailroadTrack, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REMOVE_RAILROAD_TRACK, CmdRemoveRailroadTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_SINGLE_RAIL, CmdBuildSingleRail, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REMOVE_SINGLE_RAIL, CmdRemoveSingleRail, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_TRAIN_DEPOT, CmdBuildTrainDepot, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_SIGNALS, CmdBuildSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REMOVE_SIGNALS, CmdRemoveSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_CONVERT_RAIL, CmdConvertRail, 0, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_SIGNAL_TRACK, CmdBuildSignalTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REMOVE_SIGNAL_TRACK, CmdRemoveSignalTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) + +#endif /* RAIL_CMD_H */ diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 942cce7a5e..b3f6f4431c 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -37,6 +37,7 @@ #include "genworld.h" #include "company_gui.h" #include "road_func.h" +#include "road_cmd.h" #include "table/strings.h" #include "table/roadtypes.h" diff --git a/src/road_cmd.h b/src/road_cmd.h index 753ebd21d4..4908f72e31 100644 --- a/src/road_cmd.h +++ b/src/road_cmd.h @@ -12,8 +12,21 @@ #include "direction_type.h" #include "road_type.h" +#include "command_type.h" void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt); void UpdateNearestTownForRoadTiles(bool invalidate); +CommandProc CmdBuildLongRoad; +CommandProc CmdRemoveLongRoad; +CommandProc CmdBuildRoad; +CommandProc CmdBuildRoadDepot; +CommandProc CmdConvertRoad; + +DEF_CMD_TRAIT(CMD_BUILD_LONG_ROAD, CmdBuildLongRoad, CMD_AUTO | CMD_NO_WATER | CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REMOVE_LONG_ROAD, CmdRemoveLongRoad, CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // towns may disallow removing road bits (as they are connected) in test, but in exec they're removed and thus removing is allowed. +DEF_CMD_TRAIT(CMD_BUILD_ROAD, CmdBuildRoad, CMD_AUTO | CMD_NO_WATER | CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_ROAD_DEPOT, CmdBuildRoadDepot, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_CONVERT_ROAD, CmdConvertRoad, 0, CMDT_LANDSCAPE_CONSTRUCTION) + #endif /* ROAD_CMD_H */ diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index b20748fa05..9e72fd30d8 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -34,6 +34,7 @@ #include "newgrf.h" #include "zoom_func.h" #include "framerate_type.h" +#include "roadveh_cmd.h" #include "table/strings.h" diff --git a/src/roadveh_cmd.h b/src/roadveh_cmd.h new file mode 100644 index 0000000000..42053df16d --- /dev/null +++ b/src/roadveh_cmd.h @@ -0,0 +1,23 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file roadveh_cmd.h Command definitions related to road vehicles. */ + +#ifndef ROADVEH_CMD_H +#define ROADVEH_CMD_H + +#include "command_type.h" +#include "engine_type.h" +#include "vehicle_type.h" + +CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); + +CommandProc CmdTurnRoadVeh; + +DEF_CMD_TRAIT(CMD_TURN_ROADVEH, CmdTurnRoadVeh, 0, CMDT_VEHICLE_MANAGEMENT) + +#endif /* ROADVEH_CMD_H */ diff --git a/src/settings.cpp b/src/settings.cpp index b82fe6d9a1..10d87cf9d4 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -44,6 +44,7 @@ #include "newgrf_config.h" #include "fios.h" #include "fileio_func.h" +#include "settings_cmd.h" #include "table/strings.h" diff --git a/src/settings_cmd.h b/src/settings_cmd.h new file mode 100644 index 0000000000..15b9c31a48 --- /dev/null +++ b/src/settings_cmd.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file settings_cmd.h Command definitions related to settings. */ + +#ifndef SETTINGS_CMD_H +#define SETTINGS_CMD_H + +#include "command_type.h" + +CommandProc CmdChangeSetting; +CommandProc CmdChangeCompanySetting; + +DEF_CMD_TRAIT(CMD_CHANGE_SETTING, CmdChangeSetting, CMD_SERVER, CMDT_SERVER_SETTING) +DEF_CMD_TRAIT(CMD_CHANGE_COMPANY_SETTING, CmdChangeCompanySetting, 0, CMDT_COMPANY_SETTING) + +#endif /* SETTINGS_CMD_H */ diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 7f9dab0f1a..bab291b8a5 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -34,6 +34,7 @@ #include "framerate_type.h" #include "industry.h" #include "industry_map.h" +#include "ship_cmd.h" #include "table/strings.h" diff --git a/src/ship_cmd.h b/src/ship_cmd.h new file mode 100644 index 0000000000..a451cf0a40 --- /dev/null +++ b/src/ship_cmd.h @@ -0,0 +1,19 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file ship_cmd.h Command definitions related to ships. */ + +#ifndef SHIP_CMD_H +#define SHIP_CMD_H + +#include "command_type.h" +#include "engine_type.h" +#include "vehicle_type.h" + +CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); + +#endif /* SHIP_CMD_H */ diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index 504bae0781..8aa3987556 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -17,6 +17,7 @@ #include "viewport_kdtree.h" #include "window_func.h" #include "string_func.h" +#include "signs_cmd.h" #include "table/strings.h" diff --git a/src/signs_cmd.h b/src/signs_cmd.h new file mode 100644 index 0000000000..85f0ffbdf5 --- /dev/null +++ b/src/signs_cmd.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file signs_cmd.h Command definitions related to signs. */ + +#ifndef SIGNS_CMD_H +#define SIGNS_CMD_H + +#include "command_type.h" + +CommandProc CmdPlaceSign; +CommandProc CmdRenameSign; + +DEF_CMD_TRAIT(CMD_PLACE_SIGN, CmdPlaceSign, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_RENAME_SIGN, CmdRenameSign, CMD_DEITY, CMDT_OTHER_MANAGEMENT) + +#endif /* SIGNS_CMD_H */ diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 713d383743..20ef6c997a 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -56,6 +56,8 @@ #include "linkgraph/refresh.h" #include "widgets/station_widget.h" #include "tunnelbridge_map.h" +#include "station_cmd.h" +#include "waypoint_cmd.h" #include "table/strings.h" diff --git a/src/station_cmd.h b/src/station_cmd.h new file mode 100644 index 0000000000..8e1facc250 --- /dev/null +++ b/src/station_cmd.h @@ -0,0 +1,33 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file station_cmd.h Command definitions related to stations. */ + +#ifndef STATION_CMD_H +#define STATION_CMD_H + +#include "command_type.h" + +CommandProc CmdBuildAirport; +CommandProc CmdBuildDock; +CommandProc CmdBuildRailStation; +CommandProc CmdRemoveFromRailStation; +CommandProc CmdBuildRoadStop; +CommandProc CmdRemoveRoadStop; +CommandProc CmdRenameStation; +CommandProc CmdOpenCloseAirport; + +DEF_CMD_TRAIT(CMD_BUILD_AIRPORT, CmdBuildAirport, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_DOCK, CmdBuildDock, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_RAIL_STATION, CmdBuildRailStation, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REMOVE_FROM_RAIL_STATION, CmdRemoveFromRailStation, 0, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_ROAD_STOP, CmdBuildRoadStop, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REMOVE_ROAD_STOP, CmdRemoveRoadStop, 0, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_RENAME_STATION, CmdRenameStation, 0, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_OPEN_CLOSE_AIRPORT, CmdOpenCloseAirport, 0, CMDT_ROUTE_MANAGEMENT) + +#endif /* STATION_CMD_H */ diff --git a/src/story.cpp b/src/story.cpp index 641ed7fbf5..4c58b19a5c 100644 --- a/src/story.cpp +++ b/src/story.cpp @@ -25,6 +25,7 @@ #include "game/game.hpp" #include "script/api/script_story_page.hpp" #include "script/api/script_event_types.hpp" +#include "story_cmd.h" #include "safeguards.h" diff --git a/src/story_cmd.h b/src/story_cmd.h new file mode 100644 index 0000000000..a7323ec6bf --- /dev/null +++ b/src/story_cmd.h @@ -0,0 +1,35 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file story_cmd.h Command definitions related to stories. */ + +#ifndef STORY_CMD_H +#define STORY_CMD_H + +#include "command_type.h" + +CommandProc CmdCreateStoryPage; +CommandProc CmdCreateStoryPageElement; +CommandProc CmdUpdateStoryPageElement; +CommandProc CmdSetStoryPageTitle; +CommandProc CmdSetStoryPageDate; +CommandProc CmdShowStoryPage; +CommandProc CmdRemoveStoryPage; +CommandProc CmdRemoveStoryPageElement; +CommandProc CmdStoryPageButton; + +DEF_CMD_TRAIT(CMD_CREATE_STORY_PAGE, CmdCreateStoryPage, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CREATE_STORY_PAGE_ELEMENT, CmdCreateStoryPageElement, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_UPDATE_STORY_PAGE_ELEMENT, CmdUpdateStoryPageElement, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_STORY_PAGE_TITLE, CmdSetStoryPageTitle, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_STORY_PAGE_DATE, CmdSetStoryPageDate, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SHOW_STORY_PAGE, CmdShowStoryPage, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_REMOVE_STORY_PAGE, CmdRemoveStoryPage, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_REMOVE_STORY_PAGE_ELEMENT, CmdRemoveStoryPageElement, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_STORY_PAGE_BUTTON, CmdStoryPageButton, CMD_DEITY, CMDT_OTHER_MANAGEMENT) + +#endif /* STORY_CMD_H */ diff --git a/src/subsidy.cpp b/src/subsidy.cpp index e8fc951c4e..ecead2612e 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -24,6 +24,7 @@ #include "command_func.h" #include "string_func.h" #include "tile_cmd.h" +#include "subsidy_cmd.h" #include "table/strings.h" diff --git a/src/subsidy_cmd.h b/src/subsidy_cmd.h new file mode 100644 index 0000000000..f68c9b3034 --- /dev/null +++ b/src/subsidy_cmd.h @@ -0,0 +1,19 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file subsidy_cmd.h Command definitions related to subsidies. */ + +#ifndef SUBSIDY_CMD_H +#define SUBSIDY_CMD_H + +#include "command_type.h" + +CommandProc CmdCreateSubsidy; + +DEF_CMD_TRAIT(CMD_CREATE_SUBSIDY, CmdCreateSubsidy, CMD_DEITY, CMDT_OTHER_MANAGEMENT) + +#endif /* SUBSIDY_CMD_H */ diff --git a/src/table/CMakeLists.txt b/src/table/CMakeLists.txt index c4043681b7..3a615135ef 100644 --- a/src/table/CMakeLists.txt +++ b/src/table/CMakeLists.txt @@ -34,7 +34,7 @@ add_files( town_land.h townname.h track_land.h - train_cmd.h + train_sprites.h tree_land.h unicode.h water_land.h diff --git a/src/table/train_cmd.h b/src/table/train_sprites.h similarity index 97% rename from src/table/train_cmd.h rename to src/table/train_sprites.h index f9419990b9..5811ec7f32 100644 --- a/src/table/train_cmd.h +++ b/src/table/train_sprites.h @@ -5,7 +5,7 @@ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . */ -/** @file train_cmd.h Sprites to use for trains. */ +/** @file train_sprites.h Sprites to use for trains. */ static const SpriteID _engine_sprite_base[] = { 0x0B59, 0x0B61, 0x0B69, 0x0BE1, 0x0B71, 0x0B75, 0x0B7D, 0x0B7D, diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index 205a364165..723b3953ed 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -17,6 +17,7 @@ #include "company_base.h" #include "company_func.h" #include "core/backup_type.hpp" +#include "terraform_cmd.h" #include "table/strings.h" diff --git a/src/terraform_cmd.h b/src/terraform_cmd.h new file mode 100644 index 0000000000..88aeaec4cb --- /dev/null +++ b/src/terraform_cmd.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file terraform_cmd.h Command definitions related to terraforming. */ + +#ifndef TERRAFORM_CMD_H +#define TERRAFORM_CMD_H + +#include "command_type.h" + +CommandProc CmdTerraformLand; +CommandProc CmdLevelLand; + +DEF_CMD_TRAIT(CMD_TERRAFORM_LAND, CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_LEVEL_LAND, CmdLevelLand, CMD_ALL_TILES | CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // test run might clear tiles multiple times, in execution that only happens once + +#endif /* TERRAFORM_CMD_H */ diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index b8f3adc699..a83e877a7f 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -14,6 +14,7 @@ #include "window_func.h" #include "vehicle_base.h" #include "cmd_helper.h" +#include "timetable_cmd.h" #include "table/strings.h" diff --git a/src/timetable_cmd.h b/src/timetable_cmd.h new file mode 100644 index 0000000000..ba5e2b37e2 --- /dev/null +++ b/src/timetable_cmd.h @@ -0,0 +1,25 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file timetable_cmd.h Command definitions related to timetables. */ + +#ifndef TIMETABLE_CMD_H +#define TIMETABLE_CMD_H + +#include "command_type.h" + +CommandProc CmdChangeTimetable; +CommandProc CmdSetVehicleOnTime; +CommandProc CmdAutofillTimetable; +CommandProc CmdSetTimetableStart; + +DEF_CMD_TRAIT(CMD_CHANGE_TIMETABLE, CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_VEHICLE_ON_TIME, CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_AUTOFILL_TIMETABLE, CmdAutofillTimetable, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_TIMETABLE_START, CmdSetTimetableStart, 0, CMDT_ROUTE_MANAGEMENT) + +#endif /* TIMETABLE_CMD_H */ diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 27a9e69783..542d1bc394 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -48,6 +48,7 @@ #include "object_base.h" #include "ai/ai.hpp" #include "game/game.hpp" +#include "town_cmd.h" #include "table/strings.h" #include "table/town_land.h" diff --git a/src/town_cmd.h b/src/town_cmd.h new file mode 100644 index 0000000000..bd4f4de11c --- /dev/null +++ b/src/town_cmd.h @@ -0,0 +1,35 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file town_cmd.h Command definitions related to towns. */ + +#ifndef TOWN_CMD_H +#define TOWN_CMD_H + +#include "command_type.h" + +CommandProc CmdFoundTown; +CommandProc CmdRenameTown; +CommandProc CmdDoTownAction; +CommandProc CmdTownGrowthRate; +CommandProc CmdTownRating; +CommandProc CmdTownCargoGoal; +CommandProc CmdTownSetText; +CommandProc CmdExpandTown; +CommandProc CmdDeleteTown; + +DEF_CMD_TRAIT(CMD_FOUND_TOWN, CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // founding random town can fail only in exec run +DEF_CMD_TRAIT(CMD_RENAME_TOWN, CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_DO_TOWN_ACTION, CmdDoTownAction, 0, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_TOWN_CARGO_GOAL, CmdTownCargoGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_TOWN_GROWTH_RATE, CmdTownGrowthRate, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_TOWN_RATING, CmdTownRating, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_TOWN_SET_TEXT, CmdTownSetText, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_EXPAND_TOWN, CmdExpandTown, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_DELETE_TOWN, CmdDeleteTown, CMD_OFFLINE, CMDT_LANDSCAPE_CONSTRUCTION) + +#endif /* TOWN_CMD_H */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index e0a70d14fb..ad9f6e90d3 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -34,9 +34,10 @@ #include "zoom_func.h" #include "newgrf_debug.h" #include "framerate_type.h" +#include "train_cmd.h" #include "table/strings.h" -#include "table/train_cmd.h" +#include "table/train_sprites.h" #include "safeguards.h" diff --git a/src/train_cmd.h b/src/train_cmd.h new file mode 100644 index 0000000000..3dc54678e8 --- /dev/null +++ b/src/train_cmd.h @@ -0,0 +1,28 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file train_cmd.h Command definitions related to trains. */ + +#ifndef TRAIN_CMD_H +#define TRAIN_CMD_H + +#include "command_type.h" +#include "engine_type.h" +#include "vehicle_type.h" + +CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); +CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *v, uint16 data, uint32 user); + +CommandProc CmdMoveRailVehicle; +CommandProc CmdForceTrainProceed; +CommandProc CmdReverseTrainDirection; + +DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE, CmdMoveRailVehicle, 0, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_REVERSE_TRAIN_DIRECTION, CmdReverseTrainDirection, 0, CMDT_VEHICLE_MANAGEMENT) + +#endif /* TRAIN_CMD_H */ diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index 626f0386f7..20943e02e6 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -23,6 +23,7 @@ #include "core/random_func.hpp" #include "newgrf_generic.h" #include "date_func.h" +#include "tree_cmd.h" #include "table/strings.h" #include "table/tree_land.h" diff --git a/src/tree_cmd.h b/src/tree_cmd.h new file mode 100644 index 0000000000..de8d00179b --- /dev/null +++ b/src/tree_cmd.h @@ -0,0 +1,19 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file tree_cmd.h Command definitions related to tree tiles. */ + +#ifndef TREE_CMD_H +#define TREE_CMD_H + +#include "command_type.h" + +CommandProc CmdPlantTree; + +DEF_CMD_TRAIT(CMD_PLANT_TREE, CmdPlantTree, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) + +#endif /* TREE_CMD_H */ diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 9c77dff9dc..4c7836a7a3 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -40,6 +40,7 @@ #include "water.h" #include "company_gui.h" #include "station_func.h" +#include "tunnelbridge_cmd.h" #include "table/strings.h" #include "table/bridge_land.h" diff --git a/src/tunnelbridge_cmd.h b/src/tunnelbridge_cmd.h new file mode 100644 index 0000000000..58cb9b32ae --- /dev/null +++ b/src/tunnelbridge_cmd.h @@ -0,0 +1,21 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file tunnelbridge_cmd.h Command definitions related to tunnels and bridges. */ + +#ifndef TUNNELBRIDGE_CMD_H +#define TUNNELBRIDGE_CMD_H + +#include "command_type.h" + +CommandProc CmdBuildBridge; +CommandProc CmdBuildTunnel; + +DEF_CMD_TRAIT(CMD_BUILD_BRIDGE, CmdBuildBridge, CMD_DEITY | CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_TUNNEL, CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) + +#endif /* TUNNELBRIDGE_CMD_H */ diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index a36abb59dd..472d10459b 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -30,6 +30,11 @@ #include "newgrf.h" #include "company_base.h" #include "core/random_func.hpp" +#include "vehicle_cmd.h" +#include "aircraft_cmd.h" +#include "roadveh_cmd.h" +#include "train_cmd.h" +#include "ship_cmd.h" #include #include @@ -67,13 +72,6 @@ const StringID _send_to_depot_msg_table[] = { }; -CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); -CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); -CommandCost CmdBuildShip (TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); -CommandCost CmdBuildAircraft (TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); - -CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text); - /** * Build a vehicle. * @param tile tile of depot where the vehicle is built @@ -192,8 +190,6 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint return value; } -CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *v, uint16 data, uint32 user); - /** * Sell a vehicle. * @param tile unused. diff --git a/src/vehicle_cmd.h b/src/vehicle_cmd.h new file mode 100644 index 0000000000..a2d8d62bf7 --- /dev/null +++ b/src/vehicle_cmd.h @@ -0,0 +1,39 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file vehicle_cmd.h Command definitions for vehicles. */ + +#ifndef VEHICLE_CMD_H +#define VEHICLE_CMD_H + +#include "command_type.h" + +CommandProc CmdBuildVehicle; +CommandProc CmdSellVehicle; +CommandProc CmdRefitVehicle; +CommandProc CmdSendVehicleToDepot; +CommandProc CmdChangeServiceInt; +CommandProc CmdRenameVehicle; +CommandProc CmdCloneVehicle; +CommandProc CmdStartStopVehicle; +CommandProc CmdMassStartStopVehicle; +CommandProc CmdDepotSellAllVehicles; +CommandProc CmdDepotMassAutoReplace; + +DEF_CMD_TRAIT(CMD_BUILD_VEHICLE, CmdBuildVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_SELL_VEHICLE, CmdSellVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REFIT_VEHICLE, CmdRefitVehicle, 0, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_SEND_VEHICLE_TO_DEPOT, CmdSendVehicleToDepot, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CHANGE_SERVICE_INT, CmdChangeServiceInt, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_RENAME_VEHICLE, CmdRenameVehicle, 0, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CLONE_VEHICLE, CmdCloneVehicle, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION) // NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost +DEF_CMD_TRAIT(CMD_START_STOP_VEHICLE, CmdStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_MASS_START_STOP, CmdMassStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_DEPOT_SELL_ALL_VEHICLES, CmdDepotSellAllVehicles, 0, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION) + +#endif /* VEHICLE_CMD_H */ diff --git a/src/viewport.cpp b/src/viewport.cpp index b3ccba2b5e..3a10041647 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -88,6 +88,7 @@ #include "command_func.h" #include "network/network_func.h" #include "framerate_type.h" +#include "viewport_cmd.h" #include #include diff --git a/src/viewport_cmd.h b/src/viewport_cmd.h new file mode 100644 index 0000000000..f549d755e3 --- /dev/null +++ b/src/viewport_cmd.h @@ -0,0 +1,19 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file viewport_cmd.h Command definitions related to viewports. */ + +#ifndef VIEWPORT_CMD_H +#define VIEWPORT_CMD_H + +#include "command_type.h" + +CommandProc CmdScrollViewport; + +DEF_CMD_TRAIT(CMD_SCROLL_VIEWPORT, CmdScrollViewport, CMD_DEITY, CMDT_OTHER_MANAGEMENT) + +#endif /* VIEWPORT_CMD_H */ diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 12f300ac2c..152e956b11 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -38,6 +38,7 @@ #include "company_gui.h" #include "newgrf_generic.h" #include "industry.h" +#include "water_cmd.h" #include "table/strings.h" diff --git a/src/water_cmd.h b/src/water_cmd.h new file mode 100644 index 0000000000..ccd18f7639 --- /dev/null +++ b/src/water_cmd.h @@ -0,0 +1,23 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file water_cmd.h Command definitions related to water tiles. */ + +#ifndef WATER_CMD_H +#define WATER_CMD_H + +#include "command_type.h" + +CommandProc CmdBuildShipDepot; +CommandProc CmdBuildCanal; +CommandProc CmdBuildLock; + +DEF_CMD_TRAIT(CMD_BUILD_SHIP_DEPOT, CmdBuildShipDepot, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_CANAL, CmdBuildCanal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_LOCK, CmdBuildLock, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) + +#endif /* WATER_CMD_H */ diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 77b9fbd027..d55b8f0eba 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -28,6 +28,7 @@ #include "company_base.h" #include "water.h" #include "company_gui.h" +#include "waypoint_cmd.h" #include "table/strings.h" diff --git a/src/waypoint_cmd.h b/src/waypoint_cmd.h new file mode 100644 index 0000000000..09f7ec5d3e --- /dev/null +++ b/src/waypoint_cmd.h @@ -0,0 +1,25 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file waypoint_cmd.h Command definitions related to waypoints. */ + +#ifndef WAYPOINT_CMD_H +#define WAYPOINT_CMD_H + +#include "command_type.h" + +CommandProc CmdBuildRailWaypoint; +CommandProc CmdRemoveFromRailWaypoint; +CommandProc CmdBuildBuoy; +CommandProc CmdRenameWaypoint; + +DEF_CMD_TRAIT(CMD_BUILD_RAIL_WAYPOINT, CmdBuildRailWaypoint, 0, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REMOVE_FROM_RAIL_WAYPOINT, CmdRemoveFromRailWaypoint, 0, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_BUOY, CmdBuildBuoy, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_RENAME_WAYPOINT, CmdRenameWaypoint, 0, CMDT_OTHER_MANAGEMENT) + +#endif /* WAYPOINT_CMD_H */ From 7048e1522f7095e7c716c2488d78711ab6ed912c Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 10 Oct 2021 02:08:52 +0200 Subject: [PATCH 08/60] Codechange: Move flags in CommandProc in front of the command arguments. --- src/aircraft_cmd.cpp | 4 +-- src/aircraft_cmd.h | 2 +- src/autoreplace_cmd.cpp | 8 +++--- src/command.cpp | 8 +++--- src/command_type.h | 2 +- src/company_cmd.cpp | 24 ++++++++--------- src/depot_cmd.cpp | 4 +-- src/economy.cpp | 12 ++++----- src/engine.cpp | 16 ++++++------ src/goal.cpp | 28 ++++++++++---------- src/group_cmd.cpp | 34 ++++++++++++------------ src/industry_cmd.cpp | 8 +++--- src/landscape.cpp | 8 +++--- src/misc_cmd.cpp | 20 +++++++------- src/news_gui.cpp | 4 +-- src/object_cmd.cpp | 6 ++--- src/order_backup.cpp | 4 +-- src/order_cmd.cpp | 28 ++++++++++---------- src/rail_cmd.cpp | 56 ++++++++++++++++++++-------------------- src/road_cmd.cpp | 18 ++++++------- src/roadveh_cmd.cpp | 8 +++--- src/roadveh_cmd.h | 2 +- src/settings.cpp | 8 +++--- src/ship_cmd.cpp | 4 +-- src/ship_cmd.h | 2 +- src/signs_cmd.cpp | 4 +-- src/station_cmd.cpp | 36 +++++++++++++------------- src/story.cpp | 36 +++++++++++++------------- src/subsidy.cpp | 4 +-- src/terraform_cmd.cpp | 8 +++--- src/timetable_cmd.cpp | 16 ++++++------ src/town_cmd.cpp | 36 +++++++++++++------------- src/train_cmd.cpp | 20 +++++++------- src/train_cmd.h | 2 +- src/tree_cmd.cpp | 4 +-- src/tunnelbridge_cmd.cpp | 8 +++--- src/vehicle_cmd.cpp | 52 ++++++++++++++++++------------------- src/viewport.cpp | 4 +-- src/water_cmd.cpp | 12 ++++----- src/waypoint_cmd.cpp | 12 ++++----- 40 files changed, 286 insertions(+), 286 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 2d9b2ae16a..5e0eea35bf 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -259,14 +259,14 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoff /** * Build an aircraft. - * @param tile tile of the depot where aircraft is built. * @param flags type of operation. + * @param tile tile of the depot where aircraft is built. * @param e the engine to build. * @param data unused. * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ -CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) +CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **ret) { const AircraftVehicleInfo *avi = &e->u.air; const Station *st = Station::GetByTile(tile); diff --git a/src/aircraft_cmd.h b/src/aircraft_cmd.h index 769a707c73..719974af7b 100644 --- a/src/aircraft_cmd.h +++ b/src/aircraft_cmd.h @@ -14,6 +14,6 @@ #include "engine_type.h" #include "vehicle_type.h" -CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); +CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **v); #endif /* AIRCRAFT_CMD_H */ diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index db14a4a1d4..a4a4e88a2f 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -708,14 +708,14 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /** * Autoreplaces a vehicle * Trains are replaced as a whole chain, free wagons in depot are replaced on their own - * @param tile not used * @param flags type of operation + * @param tile not used * @param p1 Index of vehicle * @param p2 not used * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Vehicle *v = Vehicle::GetIfValid(p1); if (v == nullptr) return CMD_ERROR; @@ -797,8 +797,8 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1 /** * Change engine renewal parameters - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 packed data * - bit 0 = replace when engine gets old? * - bits 16-31 = engine group @@ -808,7 +808,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1 * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetAutoReplace(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Company *c = Company::GetIfValid(_current_company); if (c == nullptr) return CMD_ERROR; diff --git a/src/command.cpp b/src/command.cpp index b875884f97..fccbe6148f 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -204,7 +204,7 @@ CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 if (_docommand_recursive == 1 || !(flags & DC_EXEC) ) { if (_docommand_recursive == 1) _cleared_object_areas.clear(); SetTownRatingTestMode(true); - res = proc(tile, flags & ~DC_EXEC, p1, p2, text); + res = proc(flags & ~DC_EXEC, tile, p1, p2, text); SetTownRatingTestMode(false); if (res.Failed()) { goto error; @@ -226,7 +226,7 @@ CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 /* Execute the command here. All cost-relevant functions set the expenses type * themselves to the cost object at some point */ if (_docommand_recursive == 1) _cleared_object_areas.clear(); - res = proc(tile, flags, p1, p2, text); + res = proc(flags, tile, p1, p2, text); if (res.Failed()) { error: _docommand_recursive--; @@ -465,7 +465,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba _cleared_object_areas.clear(); SetTownRatingTestMode(true); BasePersistentStorageArray::SwitchMode(PSM_ENTER_TESTMODE); - CommandCost res = proc(tile, flags, p1, p2, text); + CommandCost res = proc(flags, tile, p1, p2, text); BasePersistentStorageArray::SwitchMode(PSM_LEAVE_TESTMODE); SetTownRatingTestMode(false); @@ -508,7 +508,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba * use the construction one */ _cleared_object_areas.clear(); BasePersistentStorageArray::SwitchMode(PSM_ENTER_COMMAND); - CommandCost res2 = proc(tile, flags | DC_EXEC, p1, p2, text); + CommandCost res2 = proc(flags | DC_EXEC, tile, p1, p2, text); BasePersistentStorageArray::SwitchMode(PSM_LEAVE_COMMAND); if (cmd == CMD_COMPANY_CTRL) { diff --git a/src/command_type.h b/src/command_type.h index ecb24df125..2bd0fee900 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -421,7 +421,7 @@ enum CommandPauseLevel { * @param text Additional text * @return The CommandCost of the command, which can be succeeded or failed. */ -typedef CommandCost CommandProc(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text); +typedef CommandCost CommandProc(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); /** Defines the traits of a command. */ diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index f18fe343ad..f659a43673 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -795,8 +795,8 @@ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason) /** * Control the companies: add, delete, etc. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 various functionality * - bits 0..15: CompanyCtrlAction * - bits 16..23: CompanyID @@ -805,7 +805,7 @@ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCompanyCtrl(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0); CompanyID company_id = (CompanyID)GB(p1, 16, 8); @@ -922,14 +922,14 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /** * Change the company manager's face. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 unused * @param p2 face bitmasked * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CompanyManagerFace cmf = (CompanyManagerFace)p2; @@ -944,8 +944,8 @@ CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 /** * Change the company's company-colour - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 bitstuffed: * p1 bits 0-7 scheme to set * p1 bit 8 set first/second colour @@ -953,7 +953,7 @@ CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetCompanyColour(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Colours colour = Extract(p2); LiveryScheme scheme = Extract(p1); @@ -1057,14 +1057,14 @@ static bool IsUniqueCompanyName(const std::string &name) /** * Change the name of the company. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 unused * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameCompany(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { bool reset = text.empty(); @@ -1103,14 +1103,14 @@ static bool IsUniquePresidentName(const std::string &name) /** * Change the name of the president. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 unused * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenamePresident(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { bool reset = text.empty(); @@ -1188,14 +1188,14 @@ uint32 CompanyInfrastructure::GetTramTotal() const * To prevent abuse in multiplayer games you can only send money to other * companies if you have paid off your loan (either explicitly, or implicitly * given the fact that you have more money than loan). - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 the amount of money to transfer; max 20.000.000 * @param p2 the company to transfer the money to * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdGiveMoney(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (!_settings_game.economy.give_money) return CMD_ERROR; diff --git a/src/depot_cmd.cpp b/src/depot_cmd.cpp index e49936f552..1ffaeb70b2 100644 --- a/src/depot_cmd.cpp +++ b/src/depot_cmd.cpp @@ -38,14 +38,14 @@ static bool IsUniqueDepotName(const std::string &name) /** * Rename a depot. - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 id of depot * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Depot *d = Depot::GetIfValid(p1); if (d == nullptr) return CMD_ERROR; diff --git a/src/economy.cpp b/src/economy.cpp index 329a0a5a81..39e98342f9 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -2010,14 +2010,14 @@ extern int GetAmountOwnedBy(const Company *c, Owner owner); /** * Acquire shares in an opposing company. - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 company to buy the shares from * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuyShareInCompany(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CommandCost cost(EXPENSES_OTHER); CompanyID target_company = (CompanyID)p1; @@ -2062,14 +2062,14 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, /** * Sell shares in an opposing company. - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 company to sell the shares from * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSellShareInCompany(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CompanyID target_company = (CompanyID)p1; Company *c = Company::GetIfValid(target_company); @@ -2103,14 +2103,14 @@ CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1 * When a competing company is gone bankrupt you get the chance to purchase * that company. * @todo currently this only works for AI companies - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 company to buy up * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuyCompany(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CompanyID target_company = (CompanyID)p1; Company *c = Company::GetIfValid(target_company); diff --git a/src/engine.cpp b/src/engine.cpp index 56f81ffce9..e9bb6c494b 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -875,14 +875,14 @@ void ClearEnginesHiddenFlagOfCompany(CompanyID cid) /** * Set the visibility of an engine. - * @param tile Unused. * @param flags Operation to perform. + * @param tile Unused. * @param p1 Unused. * @param p2 Bit 31: 0=visible, 1=hidden, other bits for the #EngineID. * @param text Unused. * @return The cost of this operation or an error. */ -CommandCost CmdSetVehicleVisibility(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Engine *e = Engine::GetIfValid(GB(p2, 0, 31)); if (e == nullptr || _current_company >= MAX_COMPANIES) return CMD_ERROR; @@ -899,14 +899,14 @@ CommandCost CmdSetVehicleVisibility(TileIndex tile, DoCommandFlag flags, uint32 /** * Accept an engine prototype. XXX - it is possible that the top-company * changes while you are waiting to accept the offer? Then it becomes invalid - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 engine-prototype offered * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdWantEnginePreview(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdWantEnginePreview(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Engine *e = Engine::GetIfValid(p1); if (e == nullptr || !(e->flags & ENGINE_EXCLUSIVE_PREVIEW) || e->preview_company != _current_company) return CMD_ERROR; @@ -918,8 +918,8 @@ CommandCost CmdWantEnginePreview(TileIndex tile, DoCommandFlag flags, uint32 p1, /** * Allow or forbid a specific company to use an engine - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 engine id * @param p2 various bitstuffed elements * - p2 = (bit 0 - 7) - Company to allow/forbid the use of an engine. @@ -927,7 +927,7 @@ CommandCost CmdWantEnginePreview(TileIndex tile, DoCommandFlag flags, uint32 p1, * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdEngineCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdEngineCtrl(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; EngineID engine_id = (EngineID)p1; @@ -1072,14 +1072,14 @@ static bool IsUniqueEngineName(const std::string &name) /** * Rename an engine. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 engine ID to rename * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameEngine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameEngine(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Engine *e = Engine::GetIfValid(p1); if (e == nullptr) return CMD_ERROR; diff --git a/src/goal.cpp b/src/goal.cpp index 7c24386d18..a60853829d 100644 --- a/src/goal.cpp +++ b/src/goal.cpp @@ -35,8 +35,8 @@ INSTANTIATE_POOL_METHODS(Goal) /** * Create a new goal. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 various bitstuffed elements * - p1 = (bit 0 - 7) - GoalType of destination. * - p1 = (bit 8 - 15) - Company for which this goal is. @@ -44,7 +44,7 @@ INSTANTIATE_POOL_METHODS(Goal) * @param text Text of the goal. * @return the cost of this operation or an error */ -CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (!Goal::CanAllocateItem()) return CMD_ERROR; @@ -110,14 +110,14 @@ CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /** * Remove a goal. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 GoalID to remove. * @param p2 unused. * @param text unused. * @return the cost of this operation or an error */ -CommandCost CmdRemoveGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; if (!Goal::IsValidID(p1)) return CMD_ERROR; @@ -140,14 +140,14 @@ CommandCost CmdRemoveGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /** * Update goal text of a goal. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 GoalID to update. * @param p2 unused * @param text Text of the goal. * @return the cost of this operation or an error */ -CommandCost CmdSetGoalText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGoalText(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; if (!Goal::IsValidID(p1)) return CMD_ERROR; @@ -170,14 +170,14 @@ CommandCost CmdSetGoalText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /** * Update progress text of a goal. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 GoalID to update. * @param p2 unused * @param text Progress text of the goal. * @return the cost of this operation or an error */ -CommandCost CmdSetGoalProgress(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGoalProgress(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; if (!Goal::IsValidID(p1)) return CMD_ERROR; @@ -203,14 +203,14 @@ CommandCost CmdSetGoalProgress(TileIndex tile, DoCommandFlag flags, uint32 p1, u /** * Update completed state of a goal. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 GoalID to update. * @param p2 completed state. If goal is completed, set to 1, otherwise 0. * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGoalCompleted(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; if (!Goal::IsValidID(p1)) return CMD_ERROR; @@ -231,8 +231,8 @@ CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, /** * Ask a goal related question - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 various bitstuffed elements * - p1 = (bit 0 - 15) - Unique ID to use for this question. * - p1 = (bit 16 - 31) - Company or client for which this question is. @@ -243,7 +243,7 @@ CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, * @param text Text of the question. * @return the cost of this operation or an error */ -CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdGoalQuestion(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { uint16 uniqueid = (uint16)GB(p1, 0, 16); CompanyID company = (CompanyID)GB(p1, 16, 8); @@ -283,14 +283,14 @@ CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /** * Reply to a goal question. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 Unique ID to use for this question. * @param p2 Button the company pressed * @param text Text of the question. * @return the cost of this operation or an error */ -CommandCost CmdGoalQuestionAnswer(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdGoalQuestionAnswer(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (p1 > UINT16_MAX) return CMD_ERROR; if (p2 >= GOAL_QUESTION_BUTTON_COUNT) return CMD_ERROR; diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index 8b67fbeae8..fbe08ffd0c 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -294,14 +294,14 @@ Group::Group(Owner owner) /** * Create a new vehicle group. - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 vehicle type * @param p2 parent groupid * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdCreateGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleType vt = Extract(p1); if (!IsCompanyBuildableVehicleType(vt)) return CMD_ERROR; @@ -343,15 +343,15 @@ CommandCost CmdCreateGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /** * Add all vehicles in the given group to the default group and then deletes the group. - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 index of array group * - p1 bit 0-15 : GroupID * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDeleteGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Group *g = Group::GetIfValid(p1); if (g == nullptr || g->owner != _current_company) return CMD_ERROR; @@ -395,8 +395,8 @@ CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /** * Alter a group - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 index of array group * - p1 bit 0-15 : GroupID * - p1 bit 16: 0 - Rename grouop @@ -405,7 +405,7 @@ CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdAlterGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAlterGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Group *g = Group::GetIfValid(GB(p1, 0, 16)); if (g == nullptr || g->owner != _current_company) return CMD_ERROR; @@ -499,8 +499,8 @@ static void AddVehicleToGroup(Vehicle *v, GroupID new_g) /** * Add a vehicle to a group - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 index of array group * - p1 bit 0-15 : GroupID * @param p2 vehicle to add to a group @@ -509,7 +509,7 @@ static void AddVehicleToGroup(Vehicle *v, GroupID new_g) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdAddVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAddVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Vehicle *v = Vehicle::GetIfValid(GB(p2, 0, 20)); GroupID new_g = p1; @@ -525,7 +525,7 @@ CommandCost CmdAddVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (new_g == NEW_GROUP) { /* Create new group. */ - CommandCost ret = CmdCreateGroup(0, flags, v->type, INVALID_GROUP, {}); + CommandCost ret = CmdCreateGroup(flags, 0, v->type, INVALID_GROUP, {}); if (ret.Failed()) return ret; new_g = _new_group_id; @@ -558,15 +558,15 @@ CommandCost CmdAddVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, u /** * Add all shared vehicles of all vehicles from a group - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 index of group array * - p1 bit 0-15 : GroupID * @param p2 type of vehicles * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdAddSharedVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleType type = Extract(p2); GroupID id_g = p1; @@ -595,15 +595,15 @@ CommandCost CmdAddSharedVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 /** * Remove all vehicles from a group - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 index of group array * - p1 bit 0-15 : GroupID * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdRemoveAllVehiclesGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { GroupID old_g = p1; Group *g = Group::GetIfValid(old_g); @@ -629,15 +629,15 @@ CommandCost CmdRemoveAllVehiclesGroup(TileIndex tile, DoCommandFlag flags, uint3 /** * Set the livery for a vehicle group. - * @param tile Unused. * @param flags Command flags. + * @param tile Unused. * @param p1 * - p1 bit 0-15 Group ID. * @param p2 * - p2 bit 8 Set secondary instead of primary colour * - p2 bit 16-23 Colour. */ -CommandCost CmdSetGroupLivery(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGroupLivery(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Group *g = Group::GetIfValid(p1); bool primary = !HasBit(p2, 8); @@ -687,8 +687,8 @@ static void SetGroupFlag(Group *g, GroupFlags flag, bool set, bool children) /** * (Un)set group flag from a group - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 index of group array * - p1 bit 0-15 : GroupID * - p1 bit 16-18 : Flag to set, by value not bit. @@ -698,7 +698,7 @@ static void SetGroupFlag(Group *g, GroupFlags flag, bool set, bool children) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSetGroupFlag(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGroupFlag(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Group *g = Group::GetIfValid(GB(p1, 0, 16)); if (g == nullptr || g->owner != _current_company) return CMD_ERROR; diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index a24f35f756..e2fa1b7769 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1973,8 +1973,8 @@ static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, Do /** * Build/Fund an industry - * @param tile tile where industry is built * @param flags of operations to conduct + * @param tile tile where industry is built * @param p1 various bitstuffed elements * - p1 = (bit 0 - 7) - industry type see build_industry.h and see industry.h * - p1 = (bit 8 - 15) - first layout to try @@ -1983,7 +1983,7 @@ static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, Do * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { IndustryType it = GB(p1, 0, 8); if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR; @@ -2062,8 +2062,8 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin /** * Change industry properties - * @param tile Unused. * @param flags Type of operation. + * @param tile Unused. * @param p1 IndustryID * @param p2 various bitstuffed elements * - p2 = (bit 0 - 7) - IndustryAction to perform @@ -2075,7 +2075,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin * @param text - Additional industry text (only used with set text action) * @return Empty cost or an error. */ -CommandCost CmdIndustryCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdIndustryCtrl(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; diff --git a/src/landscape.cpp b/src/landscape.cpp index 1cc3b1ad20..1259617ace 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -684,14 +684,14 @@ void ClearSnowLine() /** * Clear a piece of landscape - * @param tile tile to clear * @param flags of operation to conduct + * @param tile tile to clear * @param p1 unused * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdLandscapeClear(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdLandscapeClear(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CommandCost cost(EXPENSES_CONSTRUCTION); bool do_clear = false; @@ -733,15 +733,15 @@ CommandCost CmdLandscapeClear(TileIndex tile, DoCommandFlag flags, uint32 p1, ui /** * Clear a big piece of landscape - * @param tile end tile of area dragging * @param flags of operation to conduct + * @param tile end tile of area dragging * @param p1 start tile of area dragging * @param p2 various bitstuffed data. * bit 0: Whether to use the Orthogonal (0) or Diagonal (1) iterator. * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdClearArea(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (p1 >= MapSize()) return CMD_ERROR; diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index 2e70f5fdd3..243c5347aa 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -33,8 +33,8 @@ static_assert((LOAN_INTERVAL & 3) == 0); /** * Increase the loan of your company. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 higher half of amount to increase the loan with, multitude of LOAN_INTERVAL. Only used when (p2 & 3) == 2. * @param p2 (bit 2-31) - lower half of amount (lower 2 bits assumed to be 0) * (bit 0-1) - when 0: loans LOAN_INTERVAL @@ -43,7 +43,7 @@ static_assert((LOAN_INTERVAL & 3) == 0); * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdIncreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdIncreaseLoan(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Company *c = Company::Get(_current_company); @@ -81,8 +81,8 @@ CommandCost CmdIncreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /** * Decrease the loan of your company. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 higher half of amount to decrease the loan with, multitude of LOAN_INTERVAL. Only used when (p2 & 3) == 2. * @param p2 (bit 2-31) - lower half of amount (lower 2 bits assumed to be 0) * (bit 0-1) - when 0: pays back LOAN_INTERVAL @@ -91,7 +91,7 @@ CommandCost CmdIncreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdDecreaseLoan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDecreaseLoan(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Company *c = Company::Get(_current_company); @@ -144,14 +144,14 @@ static void AskUnsafeUnpauseCallback(Window *w, bool confirmed) * Set or unset a bit in the pause mode. If pause mode is zero the game is * unpaused. A bitset is used instead of a boolean value/counter to have * more control over the game when saving/loading, etc. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 the pause mode to change * @param p2 1 pauses, 0 unpauses this mode * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdPause(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { switch (p1) { case PM_PAUSED_SAVELOAD: @@ -196,29 +196,29 @@ CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, /** * Change the financial flow of your company. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 the amount of money to receive (if positive), or spend (if negative) * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdMoneyCheat(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdMoneyCheat(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { return CommandCost(EXPENSES_OTHER, -(int32)p1); } /** * Change the bank bank balance of a company by inserting or removing money without affecting the loan. - * @param tile tile to show text effect on (if not 0) * @param flags operation to perform + * @param tile tile to show text effect on (if not 0) * @param p1 the amount of money to receive (if positive), or spend (if negative) * @param p2 (bit 0-7) - the company ID. * (bit 8-15) - the expenses type which should register the cost/income @see ExpensesType. * @param text unused * @return zero cost or an error */ -CommandCost CmdChangeBankBalance(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeBankBalance(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { int32 delta = (int32)p1; CompanyID company = (CompanyID) GB(p2, 0, 8); diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 3f3b918671..75b84a4438 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -836,8 +836,8 @@ void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceTy /** * Create a new custom news item. - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 various bitstuffed elements * - p1 = (bit 0 - 7) - NewsType of the message. * - p1 = (bit 8 - 15) - NewsReferenceType of first reference. @@ -846,7 +846,7 @@ void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceTy * @param text The text of the news message. * @return the cost of this operation or an error */ -CommandCost CmdCustomNewsItem(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCustomNewsItem(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index f207d47867..b5271727ce 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -196,14 +196,14 @@ static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags); /** * Build an object object - * @param tile tile where the object will be located * @param flags type of operation + * @param tile tile where the object will be located * @param p1 the object type to build * @param p2 the view for the object * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CommandCost cost(EXPENSES_CONSTRUCTION); @@ -776,7 +776,7 @@ void GenerateObjects() default: uint8 view = RandomRange(spec->views); - if (CmdBuildObject(RandomTile(), DC_EXEC | DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, i, view, {}).Succeeded()) amount--; + if (CmdBuildObject(DC_EXEC | DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, RandomTile(), i, view, {}).Succeeded()) amount--; break; } } diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 51e1b67ff0..76c416abd3 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -141,14 +141,14 @@ void OrderBackup::DoRestore(Vehicle *v) /** * Clear an OrderBackup - * @param tile Tile related to the to-be-cleared OrderBackup. * @param flags For command. + * @param tile Tile related to the to-be-cleared OrderBackup. * @param p1 Unused. * @param p2 User that had the OrderBackup. * @param text Unused. * @return The cost of this operation or an error. */ -CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* No need to check anything. If the tile or user don't exist we just ignore it. */ if (flags & DC_EXEC) OrderBackup::ResetOfUser(tile == 0 ? INVALID_TILE : tile, p2); diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 2f366b6743..e48cc95c17 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -727,8 +727,8 @@ uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int /** * Add an order to the orderlist of a vehicle. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 various bitstuffed elements * - p1 = (bit 0 - 19) - ID of the vehicle * - p1 = (bit 24 - 31) - the selected order (if any). If the last order is given, @@ -738,7 +738,7 @@ uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdInsertOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID veh = GB(p1, 0, 20); VehicleOrderID sel_ord = GB(p1, 20, 8); @@ -1006,14 +1006,14 @@ static CommandCost DecloneOrder(Vehicle *dst, DoCommandFlag flags) /** * Delete an order from the orderlist of a vehicle. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 the ID of the vehicle * @param p2 the order to delete (max 255) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdDeleteOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDeleteOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID veh_id = GB(p1, 0, 20); VehicleOrderID sel_ord = GB(p2, 0, 8); @@ -1111,14 +1111,14 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord) /** * Goto order of order-list. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 The ID of the vehicle which order is skipped * @param p2 the selected order to which we want to skip * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSkipToOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID veh_id = GB(p1, 0, 20); VehicleOrderID sel_ord = GB(p2, 0, 8); @@ -1148,8 +1148,8 @@ CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /** * Move an order inside the orderlist - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 the ID of the vehicle * @param p2 order to move and target * bit 0-15 : the order to move @@ -1159,7 +1159,7 @@ CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 * @note The target order will move one place down in the orderlist * if you move the order upwards else it'll move it one place down */ -CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdMoveOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID veh = GB(p1, 0, 20); VehicleOrderID moving_order = GB(p2, 0, 16); @@ -1249,8 +1249,8 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /** * Modify an order in the orderlist of a vehicle. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 various bitstuffed elements * - p1 = (bit 0 - 19) - ID of the vehicle * - p1 = (bit 24 - 31) - the selected order (if any). If the last order is given, @@ -1262,7 +1262,7 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdModifyOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleOrderID sel_ord = GB(p1, 20, 8); VehicleID veh = GB(p1, 0, 20); @@ -1522,8 +1522,8 @@ static bool CheckAircraftOrderDistance(const Aircraft *v_new, const Vehicle *v_o /** * Clone/share/copy an order-list of another vehicle. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 various bitstuffed elements * - p1 = (bit 0-19) - destination vehicle to clone orders to * - p1 = (bit 30-31) - action to perform @@ -1531,7 +1531,7 @@ static bool CheckAircraftOrderDistance(const Aircraft *v_new, const Vehicle *v_o * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCloneOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID veh_src = GB(p2, 0, 20); VehicleID veh_dst = GB(p1, 0, 20); @@ -1669,8 +1669,8 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /** * Add/remove refit orders from an order - * @param tile Not used * @param flags operation to perform + * @param tile Not used * @param p1 VehicleIndex of the vehicle having the order * @param p2 bitmask * - bit 0-7 CargoID @@ -1678,7 +1678,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdOrderRefit(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdOrderRefit(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID veh = GB(p1, 0, 20); VehicleOrderID order_number = GB(p2, 16, 8); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 449254f516..af99b03ae2 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -426,8 +426,8 @@ static inline bool ValParamTrackOrientation(Track track) /** * Build a single piece of rail - * @param tile tile to build on * @param flags operation to perform + * @param tile tile to build on * @param p1 railtype of being built piece (normal, mono, maglev) * @param p2 various bitstuffed elements * - (bit 0- 2) - track-orientation, valid values: 0-5 (@see Track) @@ -435,7 +435,7 @@ static inline bool ValParamTrackOrientation(Track track) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { RailType railtype = Extract(p1); Track track = Extract(p2); @@ -616,14 +616,14 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u /** * Remove a single piece of track - * @param tile tile to remove track from * @param flags operation to perform + * @param tile tile to remove track from * @param p1 unused * @param p2 rail orientation * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Track track = Extract(p2); CommandCost cost(EXPENSES_CONSTRUCTION); @@ -873,8 +873,8 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd /** * Build or remove a stretch of railroad tracks. - * @param tile start tile of drag * @param flags operation to perform + * @param tile start tile of drag * @param p1 end tile of drag * @param p2 various bitstuffed elements * - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building @@ -885,7 +885,7 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd * @param text unused * @return the cost of this operation or an error */ -static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CommandCost total_cost(EXPENSES_CONSTRUCTION); Track track = Extract(p2); @@ -935,8 +935,8 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint3 /** * Build rail on a stretch of track. * Stub for the unified rail builder/remover - * @param tile start tile of drag * @param flags operation to perform + * @param tile start tile of drag * @param p1 end tile of drag * @param p2 various bitstuffed elements * - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev) @@ -946,16 +946,16 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint3 * @return the cost of this operation or an error * @see CmdRailTrackHelper */ -CommandCost CmdBuildRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { - return CmdRailTrackHelper(tile, flags, p1, ClrBit(p2, 9), text); + return CmdRailTrackHelper(flags, tile, p1, ClrBit(p2, 9), text); } /** * Build rail on a stretch of track. * Stub for the unified rail builder/remover - * @param tile start tile of drag * @param flags operation to perform + * @param tile start tile of drag * @param p1 end tile of drag * @param p2 various bitstuffed elements * - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building @@ -965,15 +965,15 @@ CommandCost CmdBuildRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1 * @return the cost of this operation or an error * @see CmdRailTrackHelper */ -CommandCost CmdRemoveRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { - return CmdRailTrackHelper(tile, flags, p1, SetBit(p2, 9), text); + return CmdRailTrackHelper(flags, tile, p1, SetBit(p2, 9), text); } /** * Build a train depot - * @param tile position of the train depot * @param flags operation to perform + * @param tile position of the train depot * @param p1 rail type * @param p2 bit 0..1 entrance direction (DiagDirection) * @param text unused @@ -982,7 +982,7 @@ CommandCost CmdRemoveRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p * @todo When checking for the tile slope, * distinguish between "Flat land required" and "land sloped in wrong direction" */ -CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* check railtype and valid direction for depot (0 through 3), 4 in total */ RailType railtype = Extract(p1); @@ -1039,8 +1039,8 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u * Build signals, alternate between double/single, signal/semaphore, * pre/exit/combo-signals, and what-else not. If the rail piece does not * have any signals, bit 4 (cycle signal-type) is ignored - * @param tile tile where to build the signals * @param flags operation to perform + * @param tile tile where to build the signals * @param p1 various bitstuffed elements * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum) * - p1 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal or (for bit 7) toggle variant (CTRL-toggle) @@ -1056,7 +1056,7 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u * @return the cost of this operation or an error * @todo p2 should be replaced by two bits for "along" and "against" the track. */ -CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildSingleSignal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Track track = Extract(p1); bool ctrl_pressed = HasBit(p1, 3); // was the CTRL button pressed @@ -1256,8 +1256,8 @@ static bool AdvanceSignalAutoFill(TileIndex &tile, Trackdir &trackdir, bool remo /** * Build many signals by dragging; AutoSignals - * @param tile start tile of drag * @param flags operation to perform + * @param tile start tile of drag * @param p1 end tile of drag * @param p2 various bitstuffed elements * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) @@ -1271,7 +1271,7 @@ static bool AdvanceSignalAutoFill(TileIndex &tile, Trackdir &trackdir, bool remo * @param text unused * @return the cost of this operation or an error */ -static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +static CommandCost CmdSignalTrackHelper(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CommandCost total_cost(EXPENSES_CONSTRUCTION); TileIndex start_tile = tile; @@ -1467,8 +1467,8 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin /** * Build signals on a stretch of track. * Stub for the unified signal builder/remover - * @param tile start tile of drag * @param flags operation to perform + * @param tile start tile of drag * @param p1 end tile of drag * @param p2 various bitstuffed elements * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) @@ -1482,15 +1482,15 @@ static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uin * @return the cost of this operation or an error * @see CmdSignalTrackHelper */ -CommandCost CmdBuildSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildSignalTrack(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { - return CmdSignalTrackHelper(tile, flags, p1, p2, text); + return CmdSignalTrackHelper(flags, tile, p1, p2, text); } /** * Remove signals - * @param tile coordinates where signal is being deleted from * @param flags operation to perform + * @param tile coordinates where signal is being deleted from * @param p1 various bitstuffed elements, only track information is used * - (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) * - (bit 3) - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) @@ -1499,7 +1499,7 @@ CommandCost CmdBuildSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveSingleSignal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Track track = Extract(p1); @@ -1559,8 +1559,8 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 /** * Remove signals on a stretch of track. * Stub for the unified signal builder/remover - * @param tile start tile of drag * @param flags operation to perform + * @param tile start tile of drag * @param p1 end tile of drag * @param p2 various bitstuffed elements * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) @@ -1574,9 +1574,9 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 * @return the cost of this operation or an error * @see CmdSignalTrackHelper */ -CommandCost CmdRemoveSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveSignalTrack(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { - return CmdSignalTrackHelper(tile, flags, p1, SetBit(p2, 5), text); // bit 5 is remove bit + return CmdSignalTrackHelper(flags, tile, p1, SetBit(p2, 5), text); // bit 5 is remove bit } /** Update power of train under which is the railtype being converted */ @@ -1593,8 +1593,8 @@ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data) /** * Convert one rail type to the other. You can convert normal rail to * monorail/maglev easily or vice-versa. - * @param tile end tile of rail conversion drag * @param flags operation to perform + * @param tile end tile of rail conversion drag * @param p1 start tile of drag * @param p2 various bitstuffed elements: * - p2 = (bit 0- 5) new railtype to convert to. @@ -1602,7 +1602,7 @@ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { RailType totype = Extract(p2); TileIndex area_start = p1; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index b3f6f4431c..6fa8244e1e 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -602,8 +602,8 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existi /** * Build a piece of road. - * @param tile tile where to build road * @param flags operation to perform + * @param tile tile where to build road * @param p1 bit 0..3 road pieces to build (RoadBits) * bit 4..9 road type * bit 11..12 disallowed directions to toggle @@ -611,7 +611,7 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existi * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CompanyID company = _current_company; CommandCost cost(EXPENSES_CONSTRUCTION); @@ -967,8 +967,8 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir) /** * Build a long piece of road. - * @param start_tile start tile of drag (the building cost will appear over this tile) * @param flags operation to perform + * @param start_tile start tile of drag (the building cost will appear over this tile) * @param p1 end tile of drag * @param p2 various bitstuffed elements * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1). Only used if bit 6 is set or if we are building a single tile @@ -982,7 +982,7 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) { DisallowedRoadDirections drd = DRD_NORTHBOUND; @@ -1076,8 +1076,8 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p /** * Remove a long piece of road. - * @param start_tile start tile of drag * @param flags operation to perform + * @param start_tile start tile of drag * @param p1 end tile of drag * @param p2 various bitstuffed elements * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) @@ -1087,7 +1087,7 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) { CommandCost cost(EXPENSES_CONSTRUCTION); @@ -1164,7 +1164,7 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 * @todo When checking for the tile slope, * distinguish between "Flat land required" and "land sloped in wrong direction" */ -CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { DiagDirection dir = Extract(p1); @@ -2343,15 +2343,15 @@ static void ConvertRoadTypeOwner(TileIndex tile, uint num_pieces, Owner owner, R * Convert one road subtype to another. * Not meant to convert from road to tram. * - * @param tile end tile of road conversion drag * @param flags operation to perform + * @param tile end tile of road conversion drag * @param p1 start tile of drag * @param p2 various bitstuffed elements: * - p2 = (bit 0..5) new roadtype to convert to. * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdConvertRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { RoadType to_type = Extract(p2); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 9e72fd30d8..4c83814033 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -250,14 +250,14 @@ void RoadVehUpdateCache(RoadVehicle *v, bool same_length) /** * Build a road vehicle. - * @param tile tile of the depot where road vehicle is built. * @param flags type of operation. + * @param tile tile of the depot where road vehicle is built. * @param e the engine to build. * @param data unused. * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ -CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) +CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **ret) { /* Check that the vehicle can drive on the road in question */ RoadType rt = e->u.road.roadtype; @@ -360,14 +360,14 @@ bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destinati /** * Turn a roadvehicle around. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 vehicle ID to turn * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTurnRoadVeh(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { RoadVehicle *v = RoadVehicle::GetIfValid(p1); if (v == nullptr) return CMD_ERROR; diff --git a/src/roadveh_cmd.h b/src/roadveh_cmd.h index 42053df16d..ca99dee3ab 100644 --- a/src/roadveh_cmd.h +++ b/src/roadveh_cmd.h @@ -14,7 +14,7 @@ #include "engine_type.h" #include "vehicle_type.h" -CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); +CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **v); CommandProc CmdTurnRoadVeh; diff --git a/src/settings.cpp b/src/settings.cpp index 10d87cf9d4..1bf6513044 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1486,8 +1486,8 @@ const SettingDesc *GetSettingFromName(const std::string_view name) /** * Network-safe changing of settings (server-only). - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 unused * @param p2 the new value for the setting * The new value is properly clamped to its minimum/maximum when setting @@ -1495,7 +1495,7 @@ const SettingDesc *GetSettingFromName(const std::string_view name) * @return the cost of this operation or an error * @see _settings */ -CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeSetting(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (text.empty()) return CMD_ERROR; const SettingDesc *sd = GetSettingFromName(text); @@ -1515,15 +1515,15 @@ CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uin /** * Change one of the per-company settings. - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 unused * @param p2 the new value for the setting * The new value is properly clamped to its minimum/maximum when setting * @param text the name of the company setting to change * @return the cost of this operation or an error */ -CommandCost CmdChangeCompanySetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeCompanySetting(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (text.empty()) return CMD_ERROR; const SettingDesc *sd = GetCompanySettingFromName(text.c_str()); diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index bab291b8a5..0e0bccce0f 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -838,14 +838,14 @@ void Ship::SetDestTile(TileIndex tile) /** * Build a ship. - * @param tile tile of the depot where ship is built. * @param flags type of operation. + * @param tile tile of the depot where ship is built. * @param e the engine to build. * @param data unused. * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ -CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) +CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **ret) { tile = GetShipDepotNorthTile(tile); if (flags & DC_EXEC) { diff --git a/src/ship_cmd.h b/src/ship_cmd.h index a451cf0a40..8738f54207 100644 --- a/src/ship_cmd.h +++ b/src/ship_cmd.h @@ -14,6 +14,6 @@ #include "engine_type.h" #include "vehicle_type.h" -CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); +CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **v); #endif /* SHIP_CMD_H */ diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index 8aa3987556..c025b10429 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -37,7 +37,7 @@ SignID _new_sign_id; * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdPlaceSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdPlaceSign(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* Try to locate a new sign */ if (!Sign::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_SIGNS); @@ -76,7 +76,7 @@ CommandCost CmdPlaceSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameSign(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Sign *si = Sign::GetIfValid(p1); if (si == nullptr) return CMD_ERROR; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 20ef6c997a..f53523bc31 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1237,8 +1237,8 @@ static void RestoreTrainReservation(Train *v) /** * Build rail station - * @param tile_org northern most position of station dragging/placement * @param flags operation to perform + * @param tile_org northern most position of station dragging/placement * @param p1 various bitstuffed elements * - p1 = (bit 0- 5) - railtype * - p1 = (bit 6) - orientation (Axis) @@ -1252,7 +1252,7 @@ static void RestoreTrainReservation(Train *v) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, uint32 p1, uint32 p2, const std::string &text) { /* Unpack parameters */ RailType rt = Extract(p1); @@ -1653,15 +1653,15 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_st /** * Remove a single tile from a rail station. * This allows for custom-built station with holes and weird layouts - * @param start tile of station piece to remove * @param flags operation to perform + * @param start tile of station piece to remove * @param p1 start_tile * @param p2 various bitstuffed elements * - p2 = bit 0 - if set keep the rail * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdRemoveFromRailStation(TileIndex start, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveFromRailStation(DoCommandFlag flags, TileIndex start, uint32 p1, uint32 p2, const std::string &text) { TileIndex end = p1 == 0 ? start : p1; if (start >= MapSize() || end >= MapSize()) return CMD_ERROR; @@ -1687,15 +1687,15 @@ CommandCost CmdRemoveFromRailStation(TileIndex start, DoCommandFlag flags, uint3 /** * Remove a single tile from a waypoint. * This allows for custom-built waypoint with holes and weird layouts - * @param start tile of waypoint piece to remove * @param flags operation to perform + * @param start tile of waypoint piece to remove * @param p1 start_tile * @param p2 various bitstuffed elements * - p2 = bit 0 - if set keep the rail * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdRemoveFromRailWaypoint(TileIndex start, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveFromRailWaypoint(DoCommandFlag flags, TileIndex start, uint32 p1, uint32 p2, const std::string &text) { TileIndex end = p1 == 0 ? start : p1; if (start >= MapSize() || end >= MapSize()) return CMD_ERROR; @@ -1820,8 +1820,8 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio /** * Build a bus or truck stop. - * @param tile Northernmost tile of the stop. * @param flags Operation to perform. + * @param tile Northernmost tile of the stop. * @param p1 bit 0..7: Width of the road stop. * bit 8..15: Length of the road stop. * @param p2 bit 0: 0 For bus stops, 1 for truck stops. @@ -1834,7 +1834,7 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio * @param text Unused. * @return The cost of this operation or an error. */ -CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { bool type = HasBit(p2, 0); bool is_drive_through = HasBit(p2, 1); @@ -2075,8 +2075,8 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) /** * Remove bus or truck stops. - * @param tile Northernmost tile of the removal area. * @param flags Operation to perform. + * @param tile Northernmost tile of the removal area. * @param p1 bit 0..7: Width of the removal area. * bit 8..15: Height of the removal area. * @param p2 bit 0: 0 For bus stops, 1 for truck stops. @@ -2084,7 +2084,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) * @param text Unused. * @return The cost of this operation or an error. */ -CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveRoadStop(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { uint8 width = (uint8)GB(p1, 0, 8); uint8 height = (uint8)GB(p1, 8, 8); @@ -2232,8 +2232,8 @@ void UpdateAirportsNoise() /** * Place an Airport. - * @param tile tile where airport will be built * @param flags operation to perform + * @param tile tile where airport will be built * @param p1 * - p1 = (bit 0- 7) - airport type, @see airport.h * - p1 = (bit 8-15) - airport layout @@ -2243,7 +2243,7 @@ void UpdateAirportsNoise() * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { StationID station_to_join = GB(p2, 16, 16); bool reuse = (station_to_join != NEW_STATION); @@ -2453,14 +2453,14 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags) /** * Open/close an airport to incoming aircraft. - * @param tile Unused. * @param flags Operation to perform. + * @param tile Unused. * @param p1 Station ID of the airport. * @param p2 Unused. * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdOpenCloseAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdOpenCloseAirport(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (!Station::IsValidID(p1)) return CMD_ERROR; Station *st = Station::Get(p1); @@ -2508,14 +2508,14 @@ static const byte _dock_h_chk[4] = { 1, 2, 1, 2 }; /** * Build a dock/haven. - * @param tile tile where dock will be built * @param flags operation to perform + * @param tile tile where dock will be built * @param p1 (bit 0) - allow docks directly adjacent to other docks. * @param p2 bit 16-31: station ID to join (NEW_STATION if build new one) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { StationID station_to_join = GB(p2, 16, 16); bool reuse = (station_to_join != NEW_STATION); @@ -3927,14 +3927,14 @@ static bool IsUniqueStationName(const std::string &name) /** * Rename a station - * @param tile unused * @param flags operation to perform + * @param tile unused * @param p1 station ID that is to be renamed * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameStation(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameStation(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Station *st = Station::GetIfValid(p1); if (st == nullptr) return CMD_ERROR; diff --git a/src/story.cpp b/src/story.cpp index 4c58b19a5c..24b09ade5d 100644 --- a/src/story.cpp +++ b/src/story.cpp @@ -197,15 +197,15 @@ bool StoryPageButtonData::ValidateVehicleType() const /** * Create a new story page. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 various bitstuffed elements * - p1 = (bit 0 - 7) - Company for which this story page belongs to. * @param p2 unused. * @param text Title of the story page. Null is allowed in which case a generic page title is provided by OpenTTD. * @return the cost of this operation or an error */ -CommandCost CmdCreateStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateStoryPage(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (!StoryPage::CanAllocateItem()) return CMD_ERROR; @@ -242,8 +242,8 @@ CommandCost CmdCreateStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, u /** * Create a new story page element. - * @param tile Tile location if it is a location page element, otherwise unused. * @param flags type of operation + * @param tile Tile location if it is a location page element, otherwise unused. * @param p1 various bitstuffed elements * - p1 = (bit 0 - 15) - The page which the element belongs to. * (bit 16 - 23) - Page element type @@ -251,7 +251,7 @@ CommandCost CmdCreateStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, u * @param text Text content in case it is a text or location page element * @return the cost of this operation or an error */ -CommandCost CmdCreateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateStoryPageElement(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (!StoryPageElement::CanAllocateItem()) return CMD_ERROR; @@ -292,8 +292,8 @@ CommandCost CmdCreateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint3 /** * Update a new story page element. - * @param tile Tile location if it is a location page element, otherwise unused. * @param flags type of operation + * @param tile Tile location if it is a location page element, otherwise unused. * @param p1 various bitstuffed elements * - p1 = (bit 0 - 15) - The page element to update. * (bit 16 - 31) - unused @@ -301,7 +301,7 @@ CommandCost CmdCreateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint3 * @param text Text content in case it is a text or location page element * @return the cost of this operation or an error */ -CommandCost CmdUpdateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdUpdateStoryPageElement(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { StoryPageElementID page_element_id = (StoryPageElementID)GB(p1, 0, 16); @@ -324,14 +324,14 @@ CommandCost CmdUpdateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint3 /** * Update title of a story page. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 = (bit 0 - 15) - StoryPageID to update. * @param p2 unused * @param text title text of the story page. * @return the cost of this operation or an error */ -CommandCost CmdSetStoryPageTitle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetStoryPageTitle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); @@ -354,14 +354,14 @@ CommandCost CmdSetStoryPageTitle(TileIndex tile, DoCommandFlag flags, uint32 p1, /** * Update date of a story page. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 = (bit 0 - 15) - StoryPageID to update. * @param p2 = (bit 0 - 31) - date * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSetStoryPageDate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetStoryPageDate(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); @@ -381,14 +381,14 @@ CommandCost CmdSetStoryPageDate(TileIndex tile, DoCommandFlag flags, uint32 p1, /** * Display a story page for all clients that are allowed to * view the story page. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 = (bit 0 - 15) - StoryPageID to show. * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdShowStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdShowStoryPage(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); @@ -403,14 +403,14 @@ CommandCost CmdShowStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uin } /** * Remove a story page and associated story page elements. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 = (bit 0 - 15) - StoryPageID to remove. * @param p2 unused. * @param text unused. * @return the cost of this operation or an error */ -CommandCost CmdRemoveStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveStoryPage(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; StoryPageID page_id = (StoryPageID)p1; @@ -436,14 +436,14 @@ CommandCost CmdRemoveStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, u /** * Remove a story page element - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 = (bit 0 - 15) - StoryPageElementID to remove. * @param p2 unused. * @param text unused. * @return the cost of this operation or an error */ -CommandCost CmdRemoveStoryPageElement(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveStoryPageElement(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; StoryPageElementID page_element_id = (StoryPageElementID)p1; @@ -463,14 +463,14 @@ CommandCost CmdRemoveStoryPageElement(TileIndex tile, DoCommandFlag flags, uint3 /** * Clicked/used a button on a story page. - * @param tile Tile selected, for tile selection buttons, otherwise unused. * @param flags Type of operation. + * @param tile Tile selected, for tile selection buttons, otherwise unused. * @param p1 Bit 0..15 = story page element id of button. * @param p2 ID of selected item for buttons that select an item (e.g. vehicle), otherwise unused. * @param text Unused. * @return The cost of the operation, or an error. */ -CommandCost CmdStoryPageButton(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdStoryPageButton(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { StoryPageElementID page_element_id = (StoryPageElementID)GB(p1, 0, 16); diff --git a/src/subsidy.cpp b/src/subsidy.cpp index ecead2612e..992c7a6726 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -231,8 +231,8 @@ void CreateSubsidy(CargoID cid, SourceType src_type, SourceID src, SourceType ds /** * Create a new subsidy. - * @param tile unused. * @param flags type of operation + * @param tile unused. * @param p1 various bitstuffed elements * - p1 = (bit 0 - 7) - SourceType of source. * - p1 = (bit 8 - 23) - SourceID of source. @@ -243,7 +243,7 @@ void CreateSubsidy(CargoID cid, SourceType src_type, SourceID src, SourceType ds * @param text unused. * @return the cost of this operation or an error */ -CommandCost CmdCreateSubsidy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateSubsidy(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (!Subsidy::CanAllocateItem()) return CMD_ERROR; diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index 723b3953ed..17da36ecc8 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -179,14 +179,14 @@ static CommandCost TerraformTileHeight(TerraformerState *ts, TileIndex tile, int /** * Terraform land - * @param tile tile to terraform * @param flags for this command type + * @param tile tile to terraform * @param p1 corners to terraform (SLOPE_xxx) * @param p2 direction; eg up (non-zero) or down (zero) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTerraformLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { _terraform_err_tile = INVALID_TILE; @@ -334,8 +334,8 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin /** * Levels a selected (rectangle) area of land - * @param tile end tile of area-drag * @param flags for this command type + * @param tile end tile of area-drag * @param p1 start tile of area drag * @param p2 various bitstuffed data. * bit 0: Whether to use the Orthogonal (0) or Diagonal (1) iterator. @@ -343,7 +343,7 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdLevelLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdLevelLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (p1 >= MapSize()) return CMD_ERROR; diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index a83e877a7f..c889e5374f 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -86,8 +86,8 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, /** * Change timetable data of an order. - * @param tile Not used. * @param flags Operation to perform. + * @param tile Not used. * @param p1 Various bitstuffed elements * - p1 = (bit 0-19) - Vehicle with the orders to change. * - p1 = (bit 20-27) - Order index to modify. @@ -98,7 +98,7 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID veh = GB(p1, 0, 20); @@ -184,15 +184,15 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u /** * Clear the lateness counter to make the vehicle on time. - * @param tile Not used. * @param flags Operation to perform. + * @param tile Not used. * @param p1 Various bitstuffed elements * - p1 = (bit 0-19) - Vehicle with the orders to change. * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSetVehicleOnTime(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID veh = GB(p1, 0, 20); @@ -250,8 +250,8 @@ static bool VehicleTimetableSorter(Vehicle * const &a, Vehicle * const &b) /** * Set the start date of the timetable. - * @param tile Not used. * @param flags Operation to perform. + * @param tile Not used. * @param p2 Various bitstuffed elements * - p2 = (bit 0-19) - Vehicle ID. * - p2 = (bit 20) - Set to 1 to set timetable start for all vehicles sharing this order @@ -259,7 +259,7 @@ static bool VehicleTimetableSorter(Vehicle * const &a, Vehicle * const &b) * @param text Not used. * @return The error or cost of the operation. */ -CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetTimetableStart(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { bool timetable_all = HasBit(p1, 20); Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20)); @@ -315,8 +315,8 @@ CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, * Start or stop filling the timetable automatically from the time the vehicle * actually takes to complete it. When starting to autofill the current times * are cleared and the timetable will start again from scratch. - * @param tile Not used. * @param flags Operation to perform. + * @param tile Not used. * @param p1 Vehicle index. * @param p2 Various bitstuffed elements * - p2 = (bit 0) - Set to 1 to enable, 0 to disable autofill. @@ -324,7 +324,7 @@ CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdAutofillTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAutofillTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID veh = GB(p1, 0, 20); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 542d1bc394..2f961b9cb0 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1923,8 +1923,8 @@ static bool IsUniqueTownName(const std::string &name) /** * Create a new town. - * @param tile coordinates where town is built * @param flags type of operation + * @param tile coordinates where town is built * @param p1 0..1 size of the town (@see TownSize) * 2 true iff it should be a city * 3..5 town road layout (@see TownLayout) @@ -1933,7 +1933,7 @@ static bool IsUniqueTownName(const std::string &name) * @param text Custom name for the town. If empty, the town name parts will be used. * @return the cost of this operation or an error */ -CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdFoundTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { TownSize size = Extract(p1); bool city = HasBit(p1, 2); @@ -2735,14 +2735,14 @@ void ClearTownHouse(Town *t, TileIndex tile) /** * Rename a town (server-only). - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 town ID to rename * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Town *t = Town::GetIfValid(p1); if (t == nullptr) return CMD_ERROR; @@ -2786,8 +2786,8 @@ const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect) /** * Change the cargo goal of a town. - * @param tile Unused. * @param flags Type of operation. + * @param tile Unused. * @param p1 various bitstuffed elements * - p1 = (bit 0 - 15) - Town ID to cargo game of. * - p1 = (bit 16 - 23) - TownEffect to change the game of. @@ -2795,7 +2795,7 @@ const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect) * @param text Unused. * @return Empty cost or an error. */ -CommandCost CmdTownCargoGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTownCargoGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; @@ -2821,14 +2821,14 @@ CommandCost CmdTownCargoGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uin /** * Set a custom text in the Town window. - * @param tile Unused. * @param flags Type of operation. + * @param tile Unused. * @param p1 Town ID to change the text of. * @param p2 Unused. * @param text The new text (empty to remove the text). * @return Empty cost or an error. */ -CommandCost CmdTownSetText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTownSetText(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; Town *t = Town::GetIfValid(p1); @@ -2845,14 +2845,14 @@ CommandCost CmdTownSetText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /** * Change the growth rate of the town. - * @param tile Unused. * @param flags Type of operation. + * @param tile Unused. * @param p1 Town ID to cargo game of. * @param p2 Amount of days between growth, or TOWN_GROWTH_RATE_NONE, or 0 to reset custom growth rate. * @param text Unused. * @return Empty cost or an error. */ -CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTownGrowthRate(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; if (GB(p2, 16, 16) != 0) return CMD_ERROR; @@ -2885,14 +2885,14 @@ CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, ui /** * Change the rating of a company in a town - * @param tile Unused. * @param flags Type of operation. + * @param tile Unused. * @param p1 Bit 0..15 = Town ID to change, bit 16..23 = Company ID to change. * @param p2 Bit 0..15 = New rating of company (signed int16). * @param text Unused. * @return Empty cost or an error. */ -CommandCost CmdTownRating(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTownRating(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; @@ -2914,14 +2914,14 @@ CommandCost CmdTownRating(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /** * Expand a town (scenario editor only). - * @param tile Unused. * @param flags Type of operation. + * @param tile Unused. * @param p1 Town ID to expand. * @param p2 Amount to grow, or 0 to grow a random size up to the current amount of houses. * @param text Unused. * @return Empty cost or an error. */ -CommandCost CmdExpandTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdExpandTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR; Town *t = Town::GetIfValid(p1); @@ -2954,14 +2954,14 @@ CommandCost CmdExpandTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /** * Delete a town (scenario editor or worldgen only). - * @param tile Unused. * @param flags Type of operation. + * @param tile Unused. * @param p1 Town ID to delete. * @param p2 Unused. * @param text Unused. * @return Empty cost or an error. */ -CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDeleteTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR; Town *t = Town::GetIfValid(p1); @@ -3340,14 +3340,14 @@ uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t) * Do a town action. * This performs an action such as advertising, building a statue, funding buildings, * but also bribing the town-council - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 town to do the action at * @param p2 action to perform, @see _town_action_proc for the list of available actions * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdDoTownAction(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDoTownAction(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Town *t = Town::GetIfValid(p1); if (t == nullptr || p2 >= lengthof(_town_action_proc)) return CMD_ERROR; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index ad9f6e90d3..5a36d0d868 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -584,13 +584,13 @@ void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, /** * Build a railroad wagon. - * @param tile tile of the depot where rail-vehicle is built. * @param flags type of operation. + * @param tile tile of the depot where rail-vehicle is built. * @param e the engine to build. * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ -static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const Engine *e, Vehicle **ret) +static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **ret) { const RailVehicleInfo *rvi = &e->u.rail; @@ -714,18 +714,18 @@ static void AddRearEngineToMultiheadedTrain(Train *v) /** * Build a railroad vehicle. - * @param tile tile of the depot where rail-vehicle is built. * @param flags type of operation. + * @param tile tile of the depot where rail-vehicle is built. * @param e the engine to build. * @param data bit 0 prevents any free cars from being added to the train. * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ -CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) +CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **ret) { const RailVehicleInfo *rvi = &e->u.rail; - if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(tile, flags, e, ret); + if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(flags, tile, e, ret); /* Check if depot and new engine uses the same kind of tracks * * We need to see if the engine got power on the tile to avoid electric engines in non-electric depots */ @@ -1159,9 +1159,9 @@ static void NormaliseTrainHead(Train *head) /** * Move a rail vehicle around inside the depot. - * @param tile unused * @param flags type of operation * Note: DC_AUTOREPLACE is set when autoreplace tries to undo its modifications or moves vehicles to temporary locations inside the depot. + * @param tile unused * @param p1 various bitstuffed elements * - p1 (bit 0 - 19) source vehicle index * - p1 (bit 20) move all vehicles following the source vehicle @@ -1169,7 +1169,7 @@ static void NormaliseTrainHead(Train *head) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdMoveRailVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleID s = GB(p1, 0, 20); VehicleID d = GB(p2, 0, 20); @@ -1916,7 +1916,7 @@ void ReverseTrainDirection(Train *v) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdReverseTrainDirection(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Train *v = Train::GetIfValid(p1); if (v == nullptr) return CMD_ERROR; @@ -1982,14 +1982,14 @@ CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32 /** * Force a train through a red signal - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 train to ignore the red signal * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdForceTrainProceed(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdForceTrainProceed(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Train *t = Train::GetIfValid(p1); if (t == nullptr) return CMD_ERROR; diff --git a/src/train_cmd.h b/src/train_cmd.h index 3dc54678e8..f9452f1b51 100644 --- a/src/train_cmd.h +++ b/src/train_cmd.h @@ -14,7 +14,7 @@ #include "engine_type.h" #include "vehicle_type.h" -CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); +CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **v); CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *v, uint16 data, uint32 user); CommandProc CmdMoveRailVehicle; diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index 20943e02e6..a16ad7b824 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -379,14 +379,14 @@ void GenerateTrees() /** * Plant a tree. - * @param tile end tile of area-drag * @param flags type of operation + * @param tile end tile of area-drag * @param p1 tree type, TREE_INVALID means random. * @param p2 start tile of area-drag of tree plantation * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { StringID msg = INVALID_STRING_ID; CommandCost cost(EXPENSES_OTHER); diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 4c7836a7a3..07fcd4446a 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -248,8 +248,8 @@ static Money TunnelBridgeClearCost(TileIndex tile, Price base_price) /** * Build a Bridge - * @param end_tile end tile * @param flags type of operation + * @param end_tile end tile * @param p1 packed start tile coords (~ dx) * @param p2 various bitstuffed elements * - p2 = (bit 0- 7) - bridge type (hi bh) @@ -258,7 +258,7 @@ static Money TunnelBridgeClearCost(TileIndex tile, Price base_price) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, uint32 p2, const std::string &text) { CompanyID company = _current_company; @@ -623,15 +623,15 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u /** * Build Tunnel. - * @param start_tile start tile of tunnel * @param flags type of operation + * @param start_tile start tile of tunnel * @param p1 bit 0-5 railtype or roadtype * bit 8-9 transport type * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) { CompanyID company = _current_company; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 472d10459b..fe400bdab2 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -74,8 +74,8 @@ const StringID _send_to_depot_msg_table[] = { /** * Build a vehicle. - * @param tile tile of depot where the vehicle is built * @param flags for command + * @param tile tile of depot where the vehicle is built * @param p1 various bitstuffed data * bits 0-15: vehicle type being built. * bits 16-23: vehicle type specific bits passed on to the vehicle build functions. @@ -84,7 +84,7 @@ const StringID _send_to_depot_msg_table[] = { * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* Elementary check for valid location. */ if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return CMD_ERROR; @@ -137,10 +137,10 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint Vehicle *v = nullptr; switch (type) { - case VEH_TRAIN: value.AddCost(CmdBuildRailVehicle(tile, subflags, e, GB(p1, 16, 8), &v)); break; - case VEH_ROAD: value.AddCost(CmdBuildRoadVehicle(tile, subflags, e, GB(p1, 16, 8), &v)); break; - case VEH_SHIP: value.AddCost(CmdBuildShip (tile, subflags, e, GB(p1, 16, 8), &v)); break; - case VEH_AIRCRAFT: value.AddCost(CmdBuildAircraft (tile, subflags, e, GB(p1, 16, 8), &v)); break; + case VEH_TRAIN: value.AddCost(CmdBuildRailVehicle(subflags, tile, e, GB(p1, 16, 8), &v)); break; + case VEH_ROAD: value.AddCost(CmdBuildRoadVehicle(subflags, tile, e, GB(p1, 16, 8), &v)); break; + case VEH_SHIP: value.AddCost(CmdBuildShip (subflags, tile, e, GB(p1, 16, 8), &v)); break; + case VEH_AIRCRAFT: value.AddCost(CmdBuildAircraft (subflags, tile, e, GB(p1, 16, 8), &v)); break; default: NOT_REACHED(); // Safe due to IsDepotTile() } @@ -152,7 +152,7 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint if (refitting) { /* Refit only one vehicle. If we purchased an engine, it may have gained free wagons. */ - value.AddCost(CmdRefitVehicle(tile, flags, v->index, cargo | (1 << 16), {})); + value.AddCost(CmdRefitVehicle(flags, tile, v->index, cargo | (1 << 16), {})); } else { /* Fill in non-refitted capacities */ _returned_refit_capacity = e->GetDisplayDefaultCapacity(&_returned_mail_refit_capacity); @@ -202,7 +202,7 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint * @param text unused. * @return the cost of this operation or an error. */ -CommandCost CmdSellVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSellVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20)); if (v == nullptr) return CMD_ERROR; @@ -451,8 +451,8 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, /** * Refits a vehicle to the specified cargo type. - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 vehicle ID to refit * @param p2 various bitstuffed elements * - p2 = (bit 0-7) - New cargo type to refit to. @@ -464,7 +464,7 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRefitVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Vehicle *v = Vehicle::GetIfValid(p1); if (v == nullptr) return CMD_ERROR; @@ -545,14 +545,14 @@ CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /** * Start/Stop a vehicle - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 vehicle to start/stop, don't forget to change CcStartStopVehicle if you modify this! * @param p2 bit 0: Shall the start/stop newgrf callback be evaluated (only valid with DC_AUTOREPLACE for network safety) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* Disable the effect of p2 bit 0, when DC_AUTOREPLACE is not set */ if ((flags & DC_AUTOREPLACE) == 0) SetBit(p2, 0); @@ -627,8 +627,8 @@ CommandCost CmdStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, /** * Starts or stops a lot of vehicles - * @param tile Tile of the depot where the vehicles are started/stopped (only used for depots) * @param flags type of operation + * @param tile Tile of the depot where the vehicles are started/stopped (only used for depots) * @param p1 bitmask * - bit 0 set = start vehicles, unset = stop vehicles * - bit 1 if set, then it's a vehicle list window, not a depot and Tile is ignored in this case @@ -636,7 +636,7 @@ CommandCost CmdStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdMassStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleList list; bool do_start = HasBit(p1, 0); @@ -669,14 +669,14 @@ CommandCost CmdMassStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 /** * Sells all vehicles in a depot - * @param tile Tile of the depot where the depot is * @param flags type of operation + * @param tile Tile of the depot where the depot is * @param p1 Vehicle type * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdDepotSellAllVehicles(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleList list; @@ -705,14 +705,14 @@ CommandCost CmdDepotSellAllVehicles(TileIndex tile, DoCommandFlag flags, uint32 /** * Autoreplace all vehicles in the depot - * @param tile Tile of the depot where the vehicles are * @param flags type of operation + * @param tile Tile of the depot where the vehicles are * @param p1 Type of vehicle * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdDepotMassAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { VehicleList list; CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES); @@ -809,14 +809,14 @@ static void CloneVehicleName(const Vehicle *src, Vehicle *dst) /** * Clone a vehicle. If it is a train, it will clone all the cars too - * @param tile tile of the depot where the cloned vehicle is build * @param flags type of operation + * @param tile tile of the depot where the cloned vehicle is build * @param p1 the original vehicle's index * @param p2 1 = shared orders, else copied orders * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { CommandCost total_cost(EXPENSES_NEW_VEHICLES); @@ -1029,8 +1029,8 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con /** * Send a vehicle to the depot. - * @param tile unused * @param flags for command type + * @param tile unused * @param p1 bitmask * - p1 0-20: bitvehicle ID to send to the depot * - p1 bits 25-8 - DEPOT_ flags (see vehicle_type.h) @@ -1038,7 +1038,7 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdSendVehicleToDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSendVehicleToDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (p1 & DEPOT_MASS_SEND) { /* Mass goto depot requested */ @@ -1056,14 +1056,14 @@ CommandCost CmdSendVehicleToDepot(TileIndex tile, DoCommandFlag flags, uint32 p1 /** * Give a custom name to your vehicle - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 vehicle ID to name * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Vehicle *v = Vehicle::GetIfValid(p1); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; @@ -1094,8 +1094,8 @@ CommandCost CmdRenameVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uin /** * Change the service interval of a vehicle - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 vehicle ID that is being service-interval-changed * @param p2 bitmask * - p2 = (bit 0-15) - new service interval @@ -1104,7 +1104,7 @@ CommandCost CmdRenameVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uin * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdChangeServiceInt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeServiceInt(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Vehicle *v = Vehicle::GetIfValid(p1); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; diff --git a/src/viewport.cpp b/src/viewport.cpp index 3a10041647..1509b028c6 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -3466,14 +3466,14 @@ void InitializeSpriteSorter() /** * Scroll players main viewport. - * @param tile tile to center viewport on * @param flags type of operation + * @param tile tile to center viewport on * @param p1 ViewportScrollTarget of scroll target * @param p2 company or client id depending on the target * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdScrollViewport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdScrollViewport(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; ViewportScrollTarget target = (ViewportScrollTarget)p1; diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 152e956b11..145b8084dc 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -92,14 +92,14 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile) /** * Build a ship depot. - * @param tile tile where ship depot is built * @param flags type of operation + * @param tile tile where ship depot is built * @param p1 bit 0 depot orientation (Axis) * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildShipDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Axis axis = Extract(p1); @@ -411,14 +411,14 @@ static CommandCost RemoveLock(TileIndex tile, DoCommandFlag flags) /** * Builds a lock. - * @param tile tile where to place the lock * @param flags type of operation + * @param tile tile where to place the lock * @param p1 unused * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildLock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); if (dir == INVALID_DIAGDIR) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); @@ -435,8 +435,8 @@ bool RiverModifyDesertZone(TileIndex tile, void *) /** * Build a piece of canal. - * @param tile end tile of stretch-dragging * @param flags type of operation + * @param tile end tile of stretch-dragging * @param p1 start tile of stretch-dragging * @param p2 various bitstuffed data * bits 0-1: waterclass to build. sea and river can only be built in scenario editor @@ -444,7 +444,7 @@ bool RiverModifyDesertZone(TileIndex tile, void *) * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { WaterClass wc = Extract(p2); if (p1 >= MapSize() || wc == WATER_CLASS_INVALID) return CMD_ERROR; diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index d55b8f0eba..a95d5c9540 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -161,8 +161,8 @@ extern CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta, /** * Convert existing rail to waypoint. Eg build a waypoint station over * piece of rail - * @param start_tile northern most tile where waypoint will be built * @param flags type of operation + * @param start_tile northern most tile where waypoint will be built * @param p1 various bitstuffed elements * - p1 = (bit 0- 5) - railtype (not used) * - p1 = (bit 6) - orientation (Axis) @@ -175,7 +175,7 @@ extern CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta, * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) { /* Unpack parameters */ Axis axis = Extract(p1); @@ -296,14 +296,14 @@ CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint /** * Build a buoy. - * @param tile tile where to place the buoy * @param flags operation to perform + * @param tile tile where to place the buoy * @param p1 unused * @param p2 unused * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildBuoy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (tile == 0 || !HasTileWaterGround(tile)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -407,14 +407,14 @@ static bool IsUniqueWaypointName(const std::string &name) /** * Rename a waypoint. - * @param tile unused * @param flags type of operation + * @param tile unused * @param p1 id of waypoint * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameWaypoint(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameWaypoint(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { Waypoint *wp = Waypoint::GetIfValid(p1); if (wp == nullptr) return CMD_ERROR; From 123c7f99c342aa9eb7ca505f0b49257fc8eee7ff Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 10 Oct 2021 02:35:06 +0200 Subject: [PATCH 09/60] Codechange: Move command callback declarations to the cmd header files. --- src/CMakeLists.txt | 2 ++ src/airport_cmd.h | 17 ++++++++++ src/airport_gui.cpp | 1 + src/build_vehicle_gui.cpp | 2 ++ src/command_func.h | 56 --------------------------------- src/depot_cmd.h | 2 ++ src/dock_cmd.h | 18 +++++++++++ src/dock_gui.cpp | 2 ++ src/group_cmd.h | 3 ++ src/group_gui.cpp | 1 + src/industry_cmd.h | 2 ++ src/network/network_command.cpp | 13 ++++++++ src/object_gui.cpp | 1 + src/rail_cmd.h | 5 +++ src/road_cmd.h | 5 +++ src/script/CMakeLists.txt | 1 + src/script/script_cmd.h | 18 +++++++++++ src/terraform_cmd.h | 4 +++ src/terraform_gui.cpp | 2 ++ src/town_cmd.h | 3 ++ src/train_cmd.h | 2 ++ src/tunnelbridge_cmd.h | 2 ++ src/vehicle_cmd.h | 3 ++ src/vehicle_gui.cpp | 1 + 24 files changed, 110 insertions(+), 56 deletions(-) create mode 100644 src/airport_cmd.h create mode 100644 src/dock_cmd.h create mode 100644 src/script/script_cmd.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6950e32757..dd3a6c2f06 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,6 +42,7 @@ add_files( aircraft_gui.cpp airport.cpp airport.h + airport_cmd.h airport_gui.cpp animated_tile.cpp animated_tile_func.h @@ -131,6 +132,7 @@ add_files( direction_type.h disaster_vehicle.cpp disaster_vehicle.h + dock_cmd.h dock_gui.cpp driver.cpp driver.h diff --git a/src/airport_cmd.h b/src/airport_cmd.h new file mode 100644 index 0000000000..2e27057d8c --- /dev/null +++ b/src/airport_cmd.h @@ -0,0 +1,17 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file airport_cmd.h Command definitions related to airports. */ + +#ifndef AIRPORT_CMD_H +#define AIRPORT_CMD_H + +#include "command_type.h" + +CommandCallback CcBuildAirport; + +#endif /* AIRPORT_CMD_H */ diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index a031c450c3..ca3d8aa71d 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -26,6 +26,7 @@ #include "hotkeys.h" #include "vehicle_func.h" #include "gui.h" +#include "airport_cmd.h" #include "widgets/airport_widget.h" diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index b1136ec302..34d771090a 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -30,6 +30,8 @@ #include "cargotype.h" #include "core/geometry_func.hpp" #include "autoreplace_func.h" +#include "train_cmd.h" +#include "vehicle_cmd.h" #include "widgets/build_vehicle_widget.h" diff --git a/src/command_func.h b/src/command_func.h index 15c88ea034..03bfc73f1b 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -67,60 +67,4 @@ static inline DoCommandFlag CommandFlagsToDCFlags(CommandFlags cmd_flags) return flags; } -/*** All command callbacks that exist ***/ - -/* ai/ai_instance.cpp */ -CommandCallback CcAI; - -/* airport_gui.cpp */ -CommandCallback CcBuildAirport; - -/* bridge_gui.cpp */ -CommandCallback CcBuildBridge; - -/* dock_gui.cpp */ -CommandCallback CcBuildDocks; -CommandCallback CcPlaySound_CONSTRUCTION_WATER; - -/* depot_gui.cpp */ -CommandCallback CcCloneVehicle; - -/* game/game_instance.cpp */ -CommandCallback CcGame; - -/* group_gui.cpp */ -CommandCallback CcCreateGroup; -CommandCallback CcAddVehicleNewGroup; - -/* industry_gui.cpp */ -CommandCallback CcBuildIndustry; - -/* main_gui.cpp */ -CommandCallback CcPlaySound_EXPLOSION; -CommandCallback CcPlaceSign; -CommandCallback CcTerraform; - -/* rail_gui.cpp */ -CommandCallback CcPlaySound_CONSTRUCTION_RAIL; -CommandCallback CcRailDepot; -CommandCallback CcStation; -CommandCallback CcBuildRailTunnel; - -/* road_gui.cpp */ -CommandCallback CcPlaySound_CONSTRUCTION_OTHER; -CommandCallback CcBuildRoadTunnel; -CommandCallback CcRoadDepot; -CommandCallback CcRoadStop; - -/* train_gui.cpp */ -CommandCallback CcBuildWagon; - -/* town_gui.cpp */ -CommandCallback CcFoundTown; -CommandCallback CcFoundRandomTown; - -/* vehicle_gui.cpp */ -CommandCallback CcBuildPrimaryVehicle; -CommandCallback CcStartStopVehicle; - #endif /* COMMAND_FUNC_H */ diff --git a/src/depot_cmd.h b/src/depot_cmd.h index 9c39db1e2e..cc9701fb7f 100644 --- a/src/depot_cmd.h +++ b/src/depot_cmd.h @@ -16,4 +16,6 @@ CommandProc CmdRenameDepot; DEF_CMD_TRAIT(CMD_RENAME_DEPOT, CmdRenameDepot, 0, CMDT_OTHER_MANAGEMENT) +CommandCallback CcCloneVehicle; + #endif /* DEPOT_CMD_H */ diff --git a/src/dock_cmd.h b/src/dock_cmd.h new file mode 100644 index 0000000000..d1c1324707 --- /dev/null +++ b/src/dock_cmd.h @@ -0,0 +1,18 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file dock_cmd.h Command definitions related to docks. */ + +#ifndef DOCK_CMD_H +#define DOCK_CMD_H + +#include "command_type.h" + +CommandCallback CcBuildDocks; +CommandCallback CcPlaySound_CONSTRUCTION_WATER; + +#endif /* DOCK_CMD_H */ diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index c1f6156122..0ba34e2114 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -25,6 +25,8 @@ #include "hotkeys.h" #include "gui.h" #include "zoom_func.h" +#include "tunnelbridge_cmd.h" +#include "dock_cmd.h" #include "widgets/dock_widget.h" diff --git a/src/group_cmd.h b/src/group_cmd.h index a58a6f8aa5..7f3496cc9c 100644 --- a/src/group_cmd.h +++ b/src/group_cmd.h @@ -30,4 +30,7 @@ DEF_CMD_TRAIT(CMD_REMOVE_ALL_VEHICLES_GROUP, CmdRemoveAllVehiclesGroup, 0, CMDT_ DEF_CMD_TRAIT(CMD_SET_GROUP_FLAG, CmdSetGroupFlag, 0, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_SET_GROUP_LIVERY, CmdSetGroupLivery, 0, CMDT_ROUTE_MANAGEMENT) +CommandCallback CcCreateGroup; +CommandCallback CcAddVehicleNewGroup; + #endif /* GROUP_CMD_H */ diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 316cdc4f3c..f72d9d2d6a 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -25,6 +25,7 @@ #include "company_base.h" #include "company_gui.h" #include "gui.h" +#include "group_cmd.h" #include "widgets/group_widget.h" diff --git a/src/industry_cmd.h b/src/industry_cmd.h index e1f18932a9..150b59da9b 100644 --- a/src/industry_cmd.h +++ b/src/industry_cmd.h @@ -18,4 +18,6 @@ CommandProc CmdIndustryCtrl; DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_INDUSTRY_CTRL, CmdIndustryCtrl, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +CommandCallback CcBuildIndustry; + #endif /* INDUSTRY_CMD_H */ diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 6df53d7da1..0fae6bcbf0 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -14,6 +14,19 @@ #include "../command_func.h" #include "../company_func.h" #include "../settings_type.h" +#include "../airport_cmd.h" +#include "../depot_cmd.h" +#include "../dock_cmd.h" +#include "../group_cmd.h" +#include "../industry_cmd.h" +#include "../rail_cmd.h" +#include "../road_cmd.h" +#include "../terraform_cmd.h" +#include "../town_cmd.h" +#include "../train_cmd.h" +#include "../tunnelbridge_cmd.h" +#include "../vehicle_cmd.h" +#include "../script/script_cmd.h" #include "../safeguards.h" diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 234e3eab66..a3ea3f8b17 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -24,6 +24,7 @@ #include "window_gui.h" #include "window_func.h" #include "zoom_func.h" +#include "terraform_cmd.h" #include "widgets/object_widget.h" diff --git a/src/rail_cmd.h b/src/rail_cmd.h index e625eb03db..1fb0fdee0d 100644 --- a/src/rail_cmd.h +++ b/src/rail_cmd.h @@ -34,4 +34,9 @@ DEF_CMD_TRAIT(CMD_CONVERT_RAIL, CmdConvertRail, 0, DEF_CMD_TRAIT(CMD_BUILD_SIGNAL_TRACK, CmdBuildSignalTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_REMOVE_SIGNAL_TRACK, CmdRemoveSignalTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +CommandCallback CcPlaySound_CONSTRUCTION_RAIL; +CommandCallback CcRailDepot; +CommandCallback CcStation; +CommandCallback CcBuildRailTunnel; + #endif /* RAIL_CMD_H */ diff --git a/src/road_cmd.h b/src/road_cmd.h index 4908f72e31..05f064b0bc 100644 --- a/src/road_cmd.h +++ b/src/road_cmd.h @@ -29,4 +29,9 @@ DEF_CMD_TRAIT(CMD_BUILD_ROAD, CmdBuildRoad, CMD_AUTO | CMD_NO_WATER | DEF_CMD_TRAIT(CMD_BUILD_ROAD_DEPOT, CmdBuildRoadDepot, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_CONVERT_ROAD, CmdConvertRoad, 0, CMDT_LANDSCAPE_CONSTRUCTION) +CommandCallback CcPlaySound_CONSTRUCTION_OTHER; +CommandCallback CcBuildRoadTunnel; +CommandCallback CcRoadDepot; +CommandCallback CcRoadStop; + #endif /* ROAD_CMD_H */ diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt index f4b87dc3b8..d1054ca5f8 100644 --- a/src/script/CMakeLists.txt +++ b/src/script/CMakeLists.txt @@ -5,6 +5,7 @@ if(OPTION_TOOLS_ONLY) endif() add_files( + script_cmd.h script_config.cpp script_config.hpp script_fatalerror.hpp diff --git a/src/script/script_cmd.h b/src/script/script_cmd.h new file mode 100644 index 0000000000..bf6aa50c72 --- /dev/null +++ b/src/script/script_cmd.h @@ -0,0 +1,18 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file script_cmd.h Command definitions related to scripts. */ + +#ifndef SCRIPT_CMD_H +#define SCRIPT_CMD_H + +#include "../command_type.h" + +CommandCallback CcAI; +CommandCallback CcGame; + +#endif /* SCRIPT_CMD_H */ diff --git a/src/terraform_cmd.h b/src/terraform_cmd.h index 88aeaec4cb..9b5866efaf 100644 --- a/src/terraform_cmd.h +++ b/src/terraform_cmd.h @@ -18,4 +18,8 @@ CommandProc CmdLevelLand; DEF_CMD_TRAIT(CMD_TERRAFORM_LAND, CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_LEVEL_LAND, CmdLevelLand, CMD_ALL_TILES | CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // test run might clear tiles multiple times, in execution that only happens once +CommandCallback CcPlaySound_EXPLOSION; +CommandCallback CcPlaceSign; +CommandCallback CcTerraform; + #endif /* TERRAFORM_CMD_H */ diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 0325a957ff..a558332791 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -31,7 +31,9 @@ #include "hotkeys.h" #include "engine_base.h" #include "terraform_gui.h" +#include "terraform_cmd.h" #include "zoom_func.h" +#include "rail_cmd.h" #include "widgets/terraform_widget.h" diff --git a/src/town_cmd.h b/src/town_cmd.h index bd4f4de11c..7842e7ddaa 100644 --- a/src/town_cmd.h +++ b/src/town_cmd.h @@ -32,4 +32,7 @@ DEF_CMD_TRAIT(CMD_TOWN_SET_TEXT, CmdTownSetText, CMD_DEITY | CMD_STR_CTRL, DEF_CMD_TRAIT(CMD_EXPAND_TOWN, CmdExpandTown, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_DELETE_TOWN, CmdDeleteTown, CMD_OFFLINE, CMDT_LANDSCAPE_CONSTRUCTION) +CommandCallback CcFoundTown; +CommandCallback CcFoundRandomTown; + #endif /* TOWN_CMD_H */ diff --git a/src/train_cmd.h b/src/train_cmd.h index f9452f1b51..7b286e9983 100644 --- a/src/train_cmd.h +++ b/src/train_cmd.h @@ -25,4 +25,6 @@ DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE, CmdMoveRailVehicle, 0, CMDT_VEH DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, 0, CMDT_VEHICLE_MANAGEMENT) DEF_CMD_TRAIT(CMD_REVERSE_TRAIN_DIRECTION, CmdReverseTrainDirection, 0, CMDT_VEHICLE_MANAGEMENT) +CommandCallback CcBuildWagon; + #endif /* TRAIN_CMD_H */ diff --git a/src/tunnelbridge_cmd.h b/src/tunnelbridge_cmd.h index 58cb9b32ae..6c78db48b1 100644 --- a/src/tunnelbridge_cmd.h +++ b/src/tunnelbridge_cmd.h @@ -18,4 +18,6 @@ CommandProc CmdBuildTunnel; DEF_CMD_TRAIT(CMD_BUILD_BRIDGE, CmdBuildBridge, CMD_DEITY | CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_BUILD_TUNNEL, CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +CommandCallback CcBuildBridge; + #endif /* TUNNELBRIDGE_CMD_H */ diff --git a/src/vehicle_cmd.h b/src/vehicle_cmd.h index a2d8d62bf7..e6872e838b 100644 --- a/src/vehicle_cmd.h +++ b/src/vehicle_cmd.h @@ -36,4 +36,7 @@ DEF_CMD_TRAIT(CMD_MASS_START_STOP, CmdMassStartStopVehicle, 0, DEF_CMD_TRAIT(CMD_DEPOT_SELL_ALL_VEHICLES, CmdDepotSellAllVehicles, 0, CMDT_VEHICLE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION) +CommandCallback CcBuildPrimaryVehicle; +CommandCallback CcStartStopVehicle; + #endif /* VEHICLE_CMD_H */ diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 69fb158460..abe1b9dd97 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -36,6 +36,7 @@ #include "station_base.h" #include "tilehighlight_func.h" #include "zoom_func.h" +#include "depot_cmd.h" #include "safeguards.h" From 4fc055d6e97e76faf53ff3f29e36a4a4549bf6e7 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 10 Oct 2021 17:20:27 +0200 Subject: [PATCH 10/60] Codechange: Align parameter order of command callbacks to command handlers. --- src/ai/ai_instance.cpp | 5 +++-- src/airport_gui.cpp | 2 +- src/bridge_gui.cpp | 5 +++-- src/command.cpp | 2 +- src/command_type.h | 4 +++- src/depot_gui.cpp | 5 +++-- src/dock_gui.cpp | 4 ++-- src/game/game_instance.cpp | 5 +++-- src/group_gui.cpp | 12 +++++++----- src/industry_gui.cpp | 5 +++-- src/main_gui.cpp | 2 +- src/rail_gui.cpp | 8 ++++---- src/road_gui.cpp | 14 ++++++++------ src/signs_cmd.cpp | 5 +++-- src/terraform_gui.cpp | 2 +- src/town_gui.cpp | 4 ++-- src/train_gui.cpp | 5 +++-- src/vehicle_gui.cpp | 9 ++++++--- 18 files changed, 57 insertions(+), 41 deletions(-) diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index da79d7c132..509ed70d2e 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -93,12 +93,13 @@ ScriptInfo *AIInstance::FindLibrary(const char *library, int version) /** * DoCommand callback function for all commands executed by AIs. * @param result The result of the command. + * @param cmd cmd as given to DoCommandPInternal. * @param tile The tile on which the command was executed. * @param p1 p1 as given to DoCommandPInternal. * @param p2 p2 as given to DoCommandPInternal. - * @param cmd cmd as given to DoCommandPInternal. + * @param text text as given to DoCommandPInternal. */ -void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcAI(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { /* * The company might not exist anymore. Check for this. diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index ca3d8aa71d..41fde9b8ce 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -41,7 +41,7 @@ static void ShowBuildAirportPicker(Window *parent); SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout); -void CcBuildAirport(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcBuildAirport(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index d5347989ed..3524b357c3 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -50,15 +50,16 @@ typedef GUIList GUIBridgeList; ///< List of bridges, used in #B * Callback executed after a build Bridge CMD has been called * * @param result Whether the build succeeded + * @param cmd unused * @param end_tile End tile of the bridge. * @param p1 packed start tile coords (~ dx) * @param p2 various bitstuffed elements * - p2 = (bit 0- 7) - bridge type (hi bh) * - p2 = (bit 8-13) - rail type or road types. * - p2 = (bit 15-16) - transport type. - * @param cmd unused + * @param text unused */ -void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uint32 p2, Commands cmd) +void CcBuildBridge(const CommandCost &result, Commands cmd, TileIndex end_tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile); diff --git a/src/command.cpp b/src/command.cpp index fccbe6148f..001f2ee7d1 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -318,7 +318,7 @@ static bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *call } if (!estimate_only && !only_sending && callback != nullptr) { - callback(res, tile, p1, p2, cmd); + callback(res, cmd, tile, p1, p2, text); } return res.Succeeded(); diff --git a/src/command_type.h b/src/command_type.h index 2bd0fee900..fa381ce133 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -443,12 +443,14 @@ template struct CommandTraits; * command succeeded or failed. * * @param result The result of the executed command + * @param cmd The command that was executed * @param tile The tile of the command action * @param p1 Additional data of the command * @param p1 Additional data of the command + * @param text Text of the command * @see CommandProc */ -typedef void CommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd); +typedef void CommandCallback(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); /** * Structure for buffering the build command when selecting a station to join. diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 8515258f0f..0aba48e40c 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -112,12 +112,13 @@ extern void DepotSortList(VehicleList *list); /** * This is the Callback method after the cloning attempt of a vehicle * @param result the result of the cloning command + * @param cmd unused * @param tile unused * @param p1 unused * @param p2 unused - * @param cmd unused + * @param text unused */ -void CcCloneVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcCloneVehicle(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 0ba34e2114..52b1483815 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -40,7 +40,7 @@ static void ShowBuildDocksDepotPicker(Window *parent); static Axis _ship_depot_direction; -void CcBuildDocks(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcBuildDocks(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; @@ -48,7 +48,7 @@ void CcBuildDocks(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } -void CcPlaySound_CONSTRUCTION_WATER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcPlaySound_CONSTRUCTION_WATER(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_02_CONSTRUCTION_WATER, tile); } diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp index abd0541159..47374525fa 100644 --- a/src/game/game_instance.cpp +++ b/src/game/game_instance.cpp @@ -82,12 +82,13 @@ void GameInstance::Died() /** * DoCommand callback function for all commands executed by Game Scripts. * @param result The result of the command. + * @param cmd cmd as given to DoCommandPInternal. * @param tile The tile on which the command was executed. * @param p1 p1 as given to DoCommandPInternal. * @param p2 p2 as given to DoCommandPInternal. - * @param cmd cmd as given to DoCommandPInternal. + * @param text text as given to DoCommandPInternal. */ -void CcGame(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcGame(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (Game::GetGameInstance()->DoCommandCallback(result, tile, p1, p2, cmd)) { Game::GetGameInstance()->Continue(); diff --git a/src/group_gui.cpp b/src/group_gui.cpp index f72d9d2d6a..e9ded95367 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -1141,13 +1141,14 @@ static inline VehicleGroupWindow *FindVehicleGroupWindow(VehicleType vt, Owner o /** * Opens a 'Rename group' window for newly created group. * @param result Did command succeed? + * @param cmd Unused. * @param tile Unused. * @param p1 Vehicle type. * @param p2 Unused. - * @param cmd Unused. + * @param text Unused. * @see CmdCreateGroup */ -void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcCreateGroup(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; assert(p1 <= VEH_AIRCRAFT); @@ -1159,17 +1160,18 @@ void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 /** * Open rename window after adding a vehicle to a new group via drag and drop. * @param result Did command succeed? + * @param cmd Unused. * @param tile Unused. * @param p1 Unused. * @param p2 Bit 0-19: Vehicle ID. - * @param cmd Unused. + * @param text Unused. */ -void CcAddVehicleNewGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcAddVehicleNewGroup(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; assert(Vehicle::IsValidID(GB(p2, 0, 20))); - CcCreateGroup(result, 0, Vehicle::Get(GB(p2, 0, 20))->type, 0, cmd); + CcCreateGroup(result, cmd, 0, Vehicle::Get(GB(p2, 0, 20))->type, 0, text); } /** diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index cfdd2c6ca3..5aea6f59a4 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -219,12 +219,13 @@ void SortIndustryTypes() /** * Command callback. In case of failure to build an industry, show an error message. * @param result Result of the command. + * @param cmd Unused. * @param tile Tile where the industry is placed. * @param p1 Additional data of the #CMD_BUILD_INDUSTRY command. * @param p2 Additional data of the #CMD_BUILD_INDUSTRY command. - * @param cmd Unused. + * @param text Unused. */ -void CcBuildIndustry(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcBuildIndustry(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Succeeded()) return; diff --git a/src/main_gui.cpp b/src/main_gui.cpp index d521f79d1a..a4bec45d5c 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -76,7 +76,7 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl } -void CcPlaySound_EXPLOSION(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcPlaySound_EXPLOSION(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_12_EXPLOSION, tile); } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 54bef88fdf..7cf1b0059f 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -85,7 +85,7 @@ static bool IsStationAvailable(const StationSpec *statspec) return Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res); } -void CcPlaySound_CONSTRUCTION_RAIL(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcPlaySound_CONSTRUCTION_RAIL(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); } @@ -128,7 +128,7 @@ static const DiagDirection _place_depot_extra_dir[12] = { DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_NW, DIAGDIR_NE, }; -void CcRailDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcRailDepot(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; @@ -169,7 +169,7 @@ static void PlaceRail_Waypoint(TileIndex tile) } } -void CcStation(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcStation(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; @@ -276,7 +276,7 @@ static void PlaceRail_Bridge(TileIndex tile, Window *w) } /** Command callback for building a tunnel */ -void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcBuildRailTunnel(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); diff --git a/src/road_gui.cpp b/src/road_gui.cpp index bdd4353ca8..eedcc8f59c 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -66,7 +66,7 @@ static RoadType _cur_roadtype; static DiagDirection _road_depot_orientation; static DiagDirection _road_station_picker_orientation; -void CcPlaySound_CONSTRUCTION_OTHER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcPlaySound_CONSTRUCTION_OTHER(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); } @@ -90,13 +90,14 @@ static void PlaceRoad_Bridge(TileIndex tile, Window *w) * Callback executed after a build road tunnel command has been called. * * @param result Whether the build succeeded. + * @param cmd unused * @param start_tile Starting tile of the tunnel. * @param p1 bit 0-3 railtype or roadtypes * bit 8-9 transport type * @param p2 unused - * @param cmd unused + * @param text unused */ -void CcBuildRoadTunnel(const CommandCost &result, TileIndex start_tile, uint32 p1, uint32 p2, Commands cmd) +void CcBuildRoadTunnel(const CommandCost &result, Commands cmd, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, start_tile); @@ -129,7 +130,7 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) } } -void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcRoadDepot(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; @@ -142,6 +143,7 @@ void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 /** * Command callback for building road stops. * @param result Result of the build road stop command. + * @param cmd Unused. * @param tile Start tile. * @param p1 bit 0..7: Width of the road stop. * bit 8..15: Length of the road stop. @@ -152,10 +154,10 @@ void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 * bit 3: #Axis of the road for drive-through stops. * bit 5..9: The roadtype. * bit 16..31: Station ID to join (NEW_STATION if build new one). - * @param cmd Unused. + * @param text Unused. * @see CmdBuildRoadStop */ -void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcRoadStop(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index c025b10429..cf742df835 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -110,12 +110,13 @@ CommandCost CmdRenameSign(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /** * Callback function that is called after a sign is placed * @param result of the operation + * @param cmd unused * @param tile unused * @param p1 unused * @param p2 unused - * @param cmd unused + * @param text unused */ -void CcPlaceSign(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcPlaceSign(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index a558332791..498d057aa1 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -41,7 +41,7 @@ #include "safeguards.h" -void CcTerraform(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcTerraform(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 9e1ba39680..660b1ac98a 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -1008,7 +1008,7 @@ void ShowTownDirectory() new TownDirectoryWindow(&_town_directory_desc); } -void CcFoundTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcFoundTown(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; @@ -1016,7 +1016,7 @@ void CcFoundTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } -void CcFoundRandomTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcFoundRandomTown(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Succeeded()) ScrollMainWindowToTile(Town::Get(_new_town_id)->xy); } diff --git a/src/train_gui.cpp b/src/train_gui.cpp index a630c9fbd1..7031a89684 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -22,12 +22,13 @@ /** * Callback for building wagons. * @param result The result of the command. + * @param cmd Unused. * @param tile The tile the command was executed on. * @param p1 Additional data for the command (for the #CommandProc) * @param p2 Additional data for the command (for the #CommandProc) - * @param cmd Unused. + * @param text Unused. */ -void CcBuildWagon(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcBuildWagon(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index abe1b9dd97..cac1985b96 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2616,11 +2616,13 @@ static const StringID _vehicle_msg_translation_table[][4] = { /** * This is the Callback method after attempting to start/stop a vehicle * @param result the result of the start/stop command + * @param cmd unused * @param tile unused * @param p1 vehicle ID * @param p2 unused + * @param text unused */ -void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcStartStopVehicle(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; @@ -3119,12 +3121,13 @@ void StopGlobalFollowVehicle(const Vehicle *v) /** * This is the Callback method after the construction attempt of a primary vehicle * @param result indicates completion (or not) of the operation + * @param cmd unused * @param tile unused * @param p1 unused * @param p2 unused - * @param cmd unused + * @param text unused */ -void CcBuildPrimaryVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +void CcBuildPrimaryVehicle(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { if (result.Failed()) return; From b0990fcff7358e839468e5cf811ffddc8b9d73e2 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sat, 6 Nov 2021 23:11:22 +0100 Subject: [PATCH 11/60] Codechange: Make TileIndex a "strong" typedef to give it a distinct type. This is accomplished by changing it to a single member struct with the appropriate operator overloads to make it all work with not too much source modifications. --- src/build_vehicle_gui.cpp | 6 +-- src/cargopacket.cpp | 2 +- src/company_func.h | 2 +- src/company_gui.cpp | 6 +-- src/core/CMakeLists.txt | 1 + src/core/strong_typedef_type.hpp | 73 +++++++++++++++++++++++++++++++ src/disaster_vehicle.cpp | 2 +- src/group_gui.cpp | 4 +- src/map.cpp | 2 +- src/map_func.h | 4 +- src/newgrf_railtype.cpp | 2 +- src/newgrf_roadtype.cpp | 2 +- src/news_gui.cpp | 2 +- src/saveload/oldloader_sl.cpp | 2 +- src/script/api/script_company.cpp | 2 +- src/script/api/script_types.hpp | 2 +- src/script/squirrel_helper.hpp | 3 ++ src/tile_type.h | 24 +++++++++- src/tilearea_type.h | 30 +++++++++++++ src/timetable_gui.cpp | 8 ++-- src/town_gui.cpp | 4 +- src/tree_cmd.cpp | 4 +- src/water_cmd.cpp | 6 +-- 23 files changed, 160 insertions(+), 33 deletions(-) create mode 100644 src/core/strong_typedef_type.hpp diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 34d771090a..7901b45740 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1081,7 +1081,7 @@ struct BuildVehicleWindow : Window { { this->vehicle_type = type; this->listview_mode = tile == INVALID_TILE; - this->window_number = this->listview_mode ? (int)type : tile; + this->window_number = this->listview_mode ? (int)type : (int)tile; this->sel_engine = INVALID_ENGINE; @@ -1116,7 +1116,7 @@ struct BuildVehicleWindow : Window { this->details_height = ((this->vehicle_type == VEH_TRAIN) ? 10 : 9); - this->FinishInitNested(tile == INVALID_TILE ? (int)type : tile); + this->FinishInitNested(tile == INVALID_TILE ? (int)type : (int)tile); this->owner = (tile != INVALID_TILE) ? GetTileOwner(tile) : _local_company; @@ -1683,7 +1683,7 @@ void ShowBuildVehicleWindow(TileIndex tile, VehicleType type) * so if tile == INVALID_TILE (Available XXX Window), use 'type' as unique number. * As it always is a low value, it won't collide with any real tile * number. */ - uint num = (tile == INVALID_TILE) ? (int)type : tile; + uint num = (tile == INVALID_TILE) ? (int)type : (int)tile; assert(IsCompanyBuildableVehicleType(type)); diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 86bba0261b..e9c6e1aa77 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -75,7 +75,7 @@ CargoPacket::CargoPacket(uint16 count, byte days_in_transit, StationID source, T source_id(source_id), source(source), source_xy(source_xy), - loaded_at_xy(loaded_at_xy) + loaded_at_xy(loaded_at_xy.value) { assert(count != 0); this->source_type = source_type; diff --git a/src/company_func.h b/src/company_func.h index 01f5859104..97e1e6e828 100644 --- a/src/company_func.h +++ b/src/company_func.h @@ -27,7 +27,7 @@ void UpdateLandscapingLimits(); bool CheckCompanyHasMoney(CommandCost &cost); void SubtractMoneyFromCompany(const CommandCost& cost); void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost& cost); -CommandCost CheckOwnership(Owner owner, TileIndex tile = 0); +CommandCost CheckOwnership(Owner owner, TileIndex tile = 0U); CommandCost CheckTileOwnership(TileIndex tile); extern CompanyID _local_company; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 6ab3b0aa7d..7a6e68dea7 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -2576,11 +2576,11 @@ struct CompanyWindow : Window break; case WID_C_BUY_SHARE: - DoCommandP(CMD_BUY_SHARE_IN_COMPANY, STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, 0, this->window_number, 0); + DoCommandP(CMD_BUY_SHARE_IN_COMPANY, STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, (TileIndex)0, this->window_number, 0); break; case WID_C_SELL_SHARE: - DoCommandP(CMD_SELL_SHARE_IN_COMPANY, STR_ERROR_CAN_T_SELL_25_SHARE_IN, 0, this->window_number, 0); + DoCommandP(CMD_SELL_SHARE_IN_COMPANY, STR_ERROR_CAN_T_SELL_25_SHARE_IN, (TileIndex)0, this->window_number, 0); break; case WID_C_COMPANY_PASSWORD: @@ -2771,7 +2771,7 @@ struct BuyCompanyWindow : Window { break; case WID_BC_YES: - DoCommandP(CMD_BUY_COMPANY, STR_ERROR_CAN_T_BUY_COMPANY, 0, this->window_number, 0); + DoCommandP(CMD_BUY_COMPANY, STR_ERROR_CAN_T_BUY_COMPANY, (TileIndex)0, this->window_number, 0); break; } } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index b94ed77e91..1c14067ae4 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -28,4 +28,5 @@ add_files( smallvec_type.hpp span_type.hpp string_compare_type.hpp + strong_typedef_type.hpp ) diff --git a/src/core/strong_typedef_type.hpp b/src/core/strong_typedef_type.hpp new file mode 100644 index 0000000000..b5df28b2fb --- /dev/null +++ b/src/core/strong_typedef_type.hpp @@ -0,0 +1,73 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file strong_typedef_type.hpp Type (helpers) for making a strong typedef that is a distinct type. */ + +#ifndef STRONG_TYPEDEF_TYPE_HPP +#define STRONG_TYPEDEF_TYPE_HPP + +/** Non-templated base for #StrongTypedef for use with type trait queries. */ +struct StrongTypedefBase {}; + +/** + * Templated helper to make a type-safe 'typedef' representing a single POD value. + * A normal 'typedef' is not distinct from its base type and will be treated as + * identical in many contexts. This class provides a distinct type that can still + * be assign from and compared to values of its base type. + * + * @note This is meant to be used as a base class, not directly. + * @tparam T Storage type + * @tparam Tthis Type of the derived class (i.e. the concrete usage of this class). + */ +template +struct StrongTypedef : StrongTypedefBase { + using Type = T; + + T value{}; ///< Backing storage field. + + constexpr StrongTypedef() = default; + constexpr StrongTypedef(const StrongTypedef &o) = default; + constexpr StrongTypedef(StrongTypedef &&o) = default; + + constexpr StrongTypedef(const T &value) : value(value) {} + + constexpr Tthis &operator =(const StrongTypedef &rhs) { this->value = rhs.value; return static_cast(*this); } + constexpr Tthis &operator =(StrongTypedef &&rhs) { this->value = std::move(rhs.value); return static_cast(*this); } + constexpr Tthis &operator =(const T &rhs) { this->value = rhs; return static_cast(*this); } + + explicit constexpr operator T() const { return this->value; } + + constexpr bool operator ==(const StrongTypedef &rhs) const { return this->value == rhs.value; } + constexpr bool operator !=(const StrongTypedef &rhs) const { return this->value != rhs.value; } + constexpr bool operator ==(const T &rhs) const { return this->value == rhs; } + constexpr bool operator !=(const T &rhs) const { return this->value != rhs; } +}; + +/** + * Extension of #StrongTypedef with operators for addition and subtraction. + * @tparam T Storage type + * @tparam Tthis Type of the derived class (i.e. the concrete usage of this class). + */ +template +struct StrongIntegralTypedef : StrongTypedef { + using StrongTypedef::StrongTypedef; + + constexpr Tthis &operator ++() { this->value++; return static_cast(*this); } + constexpr Tthis &operator --() { this->value--; return static_cast(*this); } + constexpr Tthis operator ++(int) { auto res = static_cast(*this); this->value++; return res; } + constexpr Tthis operator --(int) { auto res = static_cast(*this); this->value--; return res; } + + constexpr Tthis &operator +=(const Tthis &rhs) { this->value += rhs.value; return *static_cast(this); } + constexpr Tthis &operator -=(const Tthis &rhs) { this->value -= rhs.value; return *static_cast(this); } + + constexpr Tthis operator +(const Tthis &rhs) const { return Tthis{ this->value + rhs.value }; } + constexpr Tthis operator -(const Tthis &rhs) const { return Tthis{ this->value - rhs.value }; } + constexpr Tthis operator +(const T &rhs) const { return Tthis{ this->value + rhs }; } + constexpr Tthis operator -(const T &rhs) const { return Tthis{ this->value - rhs }; } +}; + +#endif /* STRONG_TYPEDEF_TYPE_HPP */ diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index 126e48f5fc..63f4188a88 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -941,7 +941,7 @@ void ReleaseDisastersTargetingIndustry(IndustryID i) /* primary disaster vehicles that have chosen target */ if (v->subtype == ST_AIRPLANE || v->subtype == ST_HELICOPTER) { /* if it has chosen target, and it is this industry (yes, dest_tile is IndustryID here), set order to "leaving map peacefully" */ - if (v->current_order.GetDestination() > 0 && v->dest_tile == i) v->current_order.SetDestination(3); + if (v->current_order.GetDestination() > 0 && v->dest_tile == (uint32)i) v->current_order.SetDestination(3); } } } diff --git a/src/group_gui.cpp b/src/group_gui.cpp index e9ded95367..8beab1884b 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -641,7 +641,7 @@ public: if (confirmed) { VehicleGroupWindow *w = (VehicleGroupWindow*)win; w->vli.index = ALL_GROUP; - DoCommandP(CMD_DELETE_GROUP, STR_ERROR_GROUP_CAN_T_DELETE, 0, w->group_confirm, 0); + DoCommandP(CMD_DELETE_GROUP, STR_ERROR_GROUP_CAN_T_DELETE, (TileIndex)0, w->group_confirm, 0); } } @@ -965,7 +965,7 @@ public: case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group assert(Group::IsValidID(this->vli.index)); - DoCommandP(CMD_REMOVE_ALL_VEHICLES_GROUP, STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, 0, this->vli.index, 0); + DoCommandP(CMD_REMOVE_ALL_VEHICLES_GROUP, STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, (TileIndex)0, this->vli.index, 0); break; default: NOT_REACHED(); } diff --git a/src/map.cpp b/src/map.cpp index 308e28e490..2a08d656e6 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -84,7 +84,7 @@ TileIndex TileAdd(TileIndex tile, TileIndexDiff add, char buf[512]; seprintf(buf, lastof(buf), "TILE_ADD(%s) when adding 0x%.4X and 0x%.4X failed", - exp, tile, add); + exp, (uint32)tile, add); #if !defined(_MSC_VER) fprintf(stderr, "%s:%d %s\n", file, line, buf); #else diff --git a/src/map_func.h b/src/map_func.h index b02ba57773..34cc5ee0ee 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -204,7 +204,7 @@ static inline TileIndex TileVirtXY(uint x, uint y) */ static inline uint TileX(TileIndex tile) { - return tile & MapMaxX(); + return tile.value & MapMaxX(); } /** @@ -214,7 +214,7 @@ static inline uint TileX(TileIndex tile) */ static inline uint TileY(TileIndex tile) { - return tile >> MapLogX(); + return tile.value >> MapLogX(); } /** diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 4719789529..c6e2b1c40d 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -18,7 +18,7 @@ /* virtual */ uint32 RailTypeScopeResolver::GetRandomBits() const { - uint tmp = CountBits(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE); + uint tmp = CountBits(static_cast(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE)); return GB(tmp, 0, 2); } diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp index e4d29e4c5e..8eb8325c74 100644 --- a/src/newgrf_roadtype.cpp +++ b/src/newgrf_roadtype.cpp @@ -18,7 +18,7 @@ /* virtual */ uint32 RoadTypeScopeResolver::GetRandomBits() const { - uint tmp = CountBits(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE); + uint tmp = CountBits(static_cast(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE)); return GB(tmp, 0, 2); } diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 75b84a4438..69ab19b3b4 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -311,7 +311,7 @@ struct NewsWindow : Window { /* Initialize viewport if it exists. */ NWidgetViewport *nvp = this->GetWidget(WID_N_VIEWPORT); if (nvp != nullptr) { - nvp->InitializeViewport(this, ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : GetReferenceTile(ni->reftype1, ni->ref1), ZOOM_LVL_NEWS); + nvp->InitializeViewport(this, ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : (uint32)GetReferenceTile(ni->reftype1, ni->ref1), ZOOM_LVL_NEWS); if (this->ni->flags & NF_NO_TRANSPARENT) nvp->disp_flags |= ND_NO_TRANSPARENCY; if ((this->ni->flags & NF_INCOLOUR) == 0) { nvp->disp_flags |= ND_SHADE_GREY; diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 8b33c02db5..cfcc6bd37f 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -1343,7 +1343,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) if (_cargo_count != 0 && CargoPacket::CanAllocateItem()) { StationID source = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source; - TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : 0; + TileIndex source_xy = (source != INVALID_STATION) ? Station::Get(source)->xy : (TileIndex)0; v->cargo.Append(new CargoPacket(_cargo_count, _cargo_days, source, source_xy, source_xy)); } } diff --git a/src/script/api/script_company.cpp b/src/script/api/script_company.cpp index dddcc950c7..876ad84c5e 100644 --- a/src/script/api/script_company.cpp +++ b/src/script/api/script_company.cpp @@ -238,7 +238,7 @@ EnforcePrecondition(false, company != COMPANY_INVALID); /* Network commands only allow 0 to indicate invalid tiles, not INVALID_TILE */ - return ScriptObject::DoCommand(tile == INVALID_TILE ? 0 : tile , (uint32)(delta), company | expenses_type << 8 , CMD_CHANGE_BANK_BALANCE); + return ScriptObject::DoCommand(tile == INVALID_TILE ? (TileIndex)0U : tile , (uint32)(delta), company | expenses_type << 8 , CMD_CHANGE_BANK_BALANCE); } /* static */ bool ScriptCompany::BuildCompanyHQ(TileIndex tile) diff --git a/src/script/api/script_types.hpp b/src/script/api/script_types.hpp index 0d652a2d2d..a570aabf7d 100644 --- a/src/script/api/script_types.hpp +++ b/src/script/api/script_types.hpp @@ -82,6 +82,7 @@ #include "../../core/overflowsafe_type.hpp" #include "../../company_type.h" +#include "../../tile_type.h" #include /* Define all types here, so we don't have to include the whole _type.h maze */ @@ -100,7 +101,6 @@ typedef uint32 StringID; ///< The ID of a string. typedef uint16 SubsidyID; ///< The ID of a subsidy. typedef uint16 StoryPageID; ///< The ID of a story page. typedef uint16 StoryPageElementID; ///< The ID of a story page element. -typedef uint32 TileIndex; ///< The ID of a tile (just named differently). typedef uint16 TownID; ///< The ID of a town. typedef uint32 VehicleID; ///< The ID of a vehicle. diff --git a/src/script/squirrel_helper.hpp b/src/script/squirrel_helper.hpp index 6a3ba6125b..7308006fa9 100644 --- a/src/script/squirrel_helper.hpp +++ b/src/script/squirrel_helper.hpp @@ -14,6 +14,7 @@ #include "../core/smallvec_type.hpp" #include "../economy_type.h" #include "../string_func.h" +#include "../tile_type.h" #include "squirrel_helper_type.hpp" template const char *GetClassName(); @@ -85,6 +86,7 @@ namespace SQConvert { template <> inline int Return (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res); return 1; } template <> inline int Return (HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, res); return 1; } template <> inline int Return (HSQUIRRELVM vm, Money res) { sq_pushinteger(vm, res); return 1; } + template <> inline int Return (HSQUIRRELVM vm, TileIndex res) { sq_pushinteger(vm, (int32)res.value); return 1; } template <> inline int Return (HSQUIRRELVM vm, bool res) { sq_pushbool (vm, res); return 1; } template <> inline int Return (HSQUIRRELVM vm, char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); free(res); } return 1; } template <> inline int Return(HSQUIRRELVM vm, const char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); } return 1; } @@ -103,6 +105,7 @@ namespace SQConvert { template <> inline int16 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } template <> inline int32 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } template <> inline int64 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } + template <> inline TileIndex GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return TileIndex((uint32)(int32)tmp); } template <> inline Money GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } template <> inline bool GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; } template <> inline void *GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; } diff --git a/src/tile_type.h b/src/tile_type.h index 73fd0e97e1..6b5514d90e 100644 --- a/src/tile_type.h +++ b/src/tile_type.h @@ -10,6 +10,8 @@ #ifndef TILE_TYPE_H #define TILE_TYPE_H +#include "core/strong_typedef_type.hpp" + static const uint TILE_SIZE = 16; ///< Tile size in world coordinates. static const uint TILE_UNIT_MASK = TILE_SIZE - 1; ///< For masking in/out the inner-tile world coordinate units. static const uint TILE_PIXELS = 32; ///< Pixel distance between tile columns/rows in #ZOOM_LVL_BASE. @@ -80,11 +82,29 @@ enum TropicZone { /** * The index/ID of a Tile. */ -typedef uint32 TileIndex; +struct TileIndex : StrongIntegralTypedef { + using StrongIntegralTypedef::StrongIntegralTypedef; + + /** Implicit conversion to the base type for e.g. array indexing. */ + constexpr operator uint32() const { return this->value; } + + /* Import operators from the base class into our overload set. */ + using StrongIntegralTypedef::operator ==; + using StrongIntegralTypedef::operator !=; + using StrongIntegralTypedef::operator +; + using StrongIntegralTypedef::operator -; + + /* Add comparison and add/sub for signed ints as e.g. 0 is signed and will + * match ambiguously when only unsigned overloads are present. */ + constexpr bool operator ==(int rhs) const { return this->value == (uint32)rhs; } + constexpr bool operator !=(int rhs) const { return this->value != (uint32)rhs; } + constexpr TileIndex operator +(int rhs) const { return { (uint32)(this->value + rhs) }; } + constexpr TileIndex operator -(int rhs) const { return { (uint32)(this->value - rhs) }; } +}; /** * The very nice invalid tile marker */ -static const TileIndex INVALID_TILE = (TileIndex)-1; +static inline constexpr TileIndex INVALID_TILE = TileIndex{ (uint32)-1 }; #endif /* TILE_TYPE_H */ diff --git a/src/tilearea_type.h b/src/tilearea_type.h index e6d9bad602..b6af998a76 100644 --- a/src/tilearea_type.h +++ b/src/tilearea_type.h @@ -147,6 +147,36 @@ public: * Allocate a new iterator that is a copy of this one. */ virtual TileIterator *Clone() const = 0; + + /** + * Equality comparison. + */ + bool operator ==(const TileIterator &rhs) const + { + return this->tile == rhs.tile; + } + /** + * Inequality comparison. + */ + bool operator !=(const TileIterator &rhs) const + { + return this->tile != rhs.tile; + } + + /** + * Equality comparison. + */ + bool operator ==(const TileIndex &rhs) const + { + return this->tile == rhs; + } + /** + * Inequality comparison. + */ + bool operator !=(const TileIndex &rhs) const + { + return this->tile != rhs; + } }; /** Iterator to iterate over a tile area (rectangle) of the map. */ diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 00ab50115d..a205a505e8 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -578,25 +578,25 @@ struct TimetableWindow : Window { case WID_VT_CLEAR_TIME: { // Clear waiting time. uint32 p1 = PackTimetableArgs(v, this->sel_index, false); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, 0); + DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, p1, 0); break; } case WID_VT_CLEAR_SPEED: { // Clear max speed button. uint32 p1 = PackTimetableArgs(v, this->sel_index, true); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, UINT16_MAX); + DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, p1, UINT16_MAX); break; } case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter. - DoCommandP(CMD_SET_VEHICLE_ON_TIME, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, 0); + DoCommandP(CMD_SET_VEHICLE_ON_TIME, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, v->index, 0); break; case WID_VT_AUTOFILL: { // Autofill the timetable. uint32 p2 = 0; if (!HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(p2, 0); if (_ctrl_pressed) SetBit(p2, 1); - DoCommandP(CMD_AUTOFILL_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, p2); + DoCommandP(CMD_AUTOFILL_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, v->index, p2); break; } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 660b1ac98a..cb88c5c005 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -474,12 +474,12 @@ public: _warn_town_no_roads = true; } - DoCommandP(CMD_EXPAND_TOWN, STR_ERROR_CAN_T_EXPAND_TOWN, 0, this->window_number, 0); + DoCommandP(CMD_EXPAND_TOWN, STR_ERROR_CAN_T_EXPAND_TOWN, (TileIndex)0, this->window_number, 0); break; } case WID_TV_DELETE: // delete town - only available on Scenario editor - DoCommandP(CMD_DELETE_TOWN, STR_ERROR_TOWN_CAN_T_DELETE, 0, this->window_number, 0); + DoCommandP(CMD_DELETE_TOWN, STR_ERROR_TOWN_CAN_T_DELETE, (TileIndex)0, this->window_number, 0); break; } } diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index a16ad7b824..ab439cd58e 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -399,7 +399,7 @@ CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 Company *c = (_game_mode != GM_EDITOR) ? Company::GetIfValid(_current_company) : nullptr; int limit = (c == nullptr ? INT32_MAX : GB(c->tree_limit, 16, 16)); - TileArea ta(tile, p2); + TileArea ta(tile, (TileIndex)p2); for (TileIndex current_tile : ta) { switch (GetTileType(current_tile)) { case MP_TREES: @@ -528,7 +528,7 @@ static void DrawTile_Trees(TileInfo *ti) /* Do not draw trees when the invisible trees setting is set */ if (IsInvisibilitySet(TO_TREES)) return; - uint tmp = CountBits(ti->tile + ti->x + ti->y); + uint tmp = CountBits(static_cast(ti->tile + ti->x + ti->y)); uint index = GB(tmp, 0, 2) + (GetTreeType(ti->tile) << 2); /* different tree styles above one of the grounds */ diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 145b8084dc..6e357f9c68 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -454,7 +454,7 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Outside the editor you can only drag canals, and not areas */ if (_game_mode != GM_EDITOR) { - TileArea ta(tile, p1); + TileArea ta(tile, (TileIndex)p1); if (ta.w != 1 && ta.h != 1) return CMD_ERROR; } @@ -462,9 +462,9 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 std::unique_ptr iter; if (HasBit(p2, 2)) { - iter = std::make_unique(tile, p1); + iter = std::make_unique(tile, (TileIndex)p1); } else { - iter = std::make_unique(tile, p1); + iter = std::make_unique(tile, (TileIndex)p1); } for (; *iter != INVALID_TILE; ++(*iter)) { From a05fd7aa50ecbee425df2d6f9015ec3ea359232f Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Thu, 28 Oct 2021 23:48:26 +0200 Subject: [PATCH 12/60] Change: [Network] Transfer command data as serialized byte stream without fixed structure. The data will be transmitted as the length followed by the serialized data. This allows the command data to be different for every command type in the future. --- src/command.cpp | 32 ++++- src/command_func.h | 7 ++ src/command_type.h | 8 ++ src/core/span_type.hpp | 2 + src/misc/CMakeLists.txt | 1 + src/misc/endian_buffer.hpp | 206 ++++++++++++++++++++++++++++++++ src/network/core/packet.cpp | 28 +++++ src/network/core/packet.h | 2 + src/network/network.cpp | 28 +++-- src/network/network_admin.cpp | 5 +- src/network/network_command.cpp | 129 ++++++++++++++++++-- src/network/network_internal.h | 13 +- src/network/network_server.cpp | 8 +- src/string.cpp | 18 +++ src/string_func.h | 3 + 15 files changed, 455 insertions(+), 35 deletions(-) create mode 100644 src/misc/endian_buffer.hpp diff --git a/src/command.cpp b/src/command.cpp index 001f2ee7d1..788c71989c 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -55,6 +55,8 @@ #include "viewport_cmd.h" #include "water_cmd.h" #include "waypoint_cmd.h" +#include "misc/endian_buffer.hpp" +#include "string_func.h" #include @@ -399,12 +401,38 @@ bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, T return DoCommandP(cmd, err_message, callback, true, false, tile, p1, p2, text); } +/** + * Toplevel network safe docommand function for the current company. Must not be called recursively. + * The callback is called when the command succeeded or failed. The parameters + * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. + * + * @param cmd The command to execute (a CMD_* value) + * @param err_message Message prefix to show on error + * @param callback A callback function to call after the command is finished + * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) + * @param tile The tile to perform a command on (see #CommandProc) + * @param p1 Additional data for the command (see #CommandProc) + * @param p2 Additional data for the command (see #CommandProc) + * @param text The text to pass + * @return \c true if the command succeeded, else \c false. + */ +bool InjectNetworkCommand(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +{ + return DoCommandP(cmd, err_message, callback, my_cmd, true, tile, p1, p2, text); +} + /** * Helper to deduplicate the code for returning. * @param cmd the command cost to return. */ #define return_dcpi(cmd) { _docommand_recursive = 0; return cmd; } +/** Helper to format command parameters into a hex string. */ +static std::string CommandParametersToHexString(TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +{ + return FormatArrayAsHex(EndianBufferWriter<>::FromValue(std::make_tuple(tile, p1, p2, text))); +} + /*! * Helper function for the toplevel network safe docommand function for the current company. * @@ -482,7 +510,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba if (!_networking || _generating_world || network_command) { /* Log the failed command as well. Just to be able to be find * causes of desyncs due to bad command test implementations. */ - Debug(desync, 1, "cmdf: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd, err_message, text, GetCommandName(cmd)); + Debug(desync, 1, "cmdf: {:08x}; {:02x}; {:02x}; {:08x}; {:08x}; {:06x}; {} ({})", _date, _date_fract, (int)_current_company, cmd, err_message, tile, CommandParametersToHexString(tile, p1, p2, text), GetCommandName(cmd)); } cur_company.Restore(); return_dcpi(res); @@ -502,7 +530,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba * reset the storages as we've not executed the command. */ return_dcpi(CommandCost()); } - Debug(desync, 1, "cmd: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd, err_message, text, GetCommandName(cmd)); + Debug(desync, 1, "cmd: {:08x}; {:02x}; {:02x}; {:08x}; {:08x}; {:06x}; {} ({})", _date, _date_fract, (int)_current_company, cmd, err_message, tile, CommandParametersToHexString(tile, p1, p2, text), GetCommandName(cmd)); /* Actually try and execute the command. If no cost-type is given * use the construction one */ diff --git a/src/command_func.h b/src/command_func.h index 03bfc73f1b..0d000755c8 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -12,6 +12,7 @@ #include "command_type.h" #include "company_type.h" +#include /** * Define a default return value for a failed command. @@ -32,6 +33,9 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); */ #define return_cmd_error(errcode) return CommandCost(errcode); +/** Storage buffer for serialized command data. */ +typedef std::vector CommandDataBuffer; + CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags); @@ -41,9 +45,12 @@ bool DoCommandP(Commands cmd, CommandCallback *callback, TileIndex tile, uint32 bool DoCommandP(Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); bool DoCommandP(const CommandContainer *container, bool my_cmd = true, bool network_command = false); +bool InjectNetworkCommand(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); + CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); +void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex location, const CommandDataBuffer &cmd_data); extern Money _additional_cash_required; diff --git a/src/command_type.h b/src/command_type.h index fa381ce133..3a15087b9a 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -424,11 +424,19 @@ enum CommandPauseLevel { typedef CommandCost CommandProc(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); +template struct CommandFunctionTraitHelper; +template +struct CommandFunctionTraitHelper { + using Args = std::tuple...>; +}; + /** Defines the traits of a command. */ template struct CommandTraits; #define DEF_CMD_TRAIT(cmd_, proc_, flags_, type_) \ template<> struct CommandTraits { \ + using Args = typename CommandFunctionTraitHelper::Args; \ + static constexpr Commands cmd = cmd_; \ static constexpr auto &proc = proc_; \ static constexpr CommandFlags flags = (CommandFlags)(flags_); \ static constexpr CommandType type = type_; \ diff --git a/src/core/span_type.hpp b/src/core/span_type.hpp index 614be84567..0df528816e 100644 --- a/src/core/span_type.hpp +++ b/src/core/span_type.hpp @@ -92,6 +92,8 @@ public: constexpr const_iterator cbegin() const noexcept { return const_iterator(first); } constexpr const_iterator cend() const noexcept { return const_iterator(last); } + constexpr reference operator[](size_type idx) const { return first[idx]; } + private: pointer first; pointer last; diff --git a/src/misc/CMakeLists.txt b/src/misc/CMakeLists.txt index ee2ca6a41c..24cde73e41 100644 --- a/src/misc/CMakeLists.txt +++ b/src/misc/CMakeLists.txt @@ -5,6 +5,7 @@ add_files( countedptr.hpp dbg_helpers.cpp dbg_helpers.h + endian_buffer.hpp fixedsizearray.hpp getoptdata.cpp getoptdata.h diff --git a/src/misc/endian_buffer.hpp b/src/misc/endian_buffer.hpp new file mode 100644 index 0000000000..c20d9a8b99 --- /dev/null +++ b/src/misc/endian_buffer.hpp @@ -0,0 +1,206 @@ +/* + * This file is part of OpenTTD. + * OpenTTD 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, version 2. + * OpenTTD 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 OpenTTD. If not, see . + */ + +/** @file endian_buffer.hpp Endian-aware buffer. */ + +#ifndef ENDIAN_BUFFER_HPP +#define ENDIAN_BUFFER_HPP + +#include +#include +#include "../core/span_type.hpp" +#include "../core/bitmath_func.hpp" + +struct StrongTypedefBase; + +/** + * Endian-aware buffer adapter that always writes values in little endian order. + * @note This class uses operator overloading (<<, just like streams) for writing + * as this allows providing custom operator overloads for more complex types + * like e.g. structs without needing to modify this class. + */ +template , typename Titer = typename std::back_insert_iterator> +class EndianBufferWriter { + /** Output iterator for the destination buffer. */ + Titer buffer; + +public: + EndianBufferWriter(Titer buffer) : buffer(buffer) {} + EndianBufferWriter(typename Titer::container_type &container) : buffer(std::back_inserter(container)) {} + + EndianBufferWriter &operator <<(const std::string &data) { return *this << std::string_view{ data }; } + EndianBufferWriter &operator <<(const char *data) { return *this << std::string_view{ data }; } + EndianBufferWriter &operator <<(std::string_view data) { this->Write(data); return *this; } + EndianBufferWriter &operator <<(bool data) { return *this << static_cast(data ? 1 : 0); } + + template + EndianBufferWriter &operator <<(const std::tuple &data) + { + this->WriteTuple(data, std::index_sequence_for{}); + return *this; + } + + template >, std::is_base_of>, int> = 0> + EndianBufferWriter &operator <<(const T data) + { + if constexpr (std::is_enum_v) { + this->Write(static_cast>(data)); + } else if constexpr (std::is_base_of_v) { + this->Write(data.value); + } else { + this->Write(data); + } + return *this; + } + + template > + static Tbuf FromValue(const Tvalue &data) + { + Tbuf buffer; + EndianBufferWriter writer{ buffer }; + writer << data; + return buffer; + } + +private: + /** Helper function to write a tuple to the buffer. */ + template + void WriteTuple(const Ttuple &values, std::index_sequence) { + ((*this << std::get(values)), ...); + } + + /** Write overload for string values. */ + void Write(std::string_view value) + { + for (auto c : value) { + this->buffer++ = c; + } + this->buffer++ = '\0'; + } + + /** Fundamental write function. */ + template + void Write(T value) + { + static_assert(sizeof(T) <= 8, "Value can't be larger than 8 bytes"); + + if constexpr (sizeof(T) > 1) { + this->buffer++ = GB(value, 0, 8); + this->buffer++ = GB(value, 8, 8); + if constexpr (sizeof(T) > 2) { + this->buffer++ = GB(value, 16, 8); + this->buffer++ = GB(value, 24, 8); + } + if constexpr (sizeof(T) > 4) { + this->buffer++ = GB(value, 32, 8); + this->buffer++ = GB(value, 40, 8); + this->buffer++ = GB(value, 48, 8); + this->buffer++ = GB(value, 56, 8); + } + } else { + this->buffer++ = value; + } + } +}; + +/** + * Endian-aware buffer adapter that always reads values in little endian order. + * @note This class uses operator overloading (>>, just like streams) for reading + * as this allows providing custom operator overloads for more complex types + * like e.g. structs without needing to modify this class. + */ +class EndianBufferReader { + /** Reference to storage buffer. */ + span buffer; + /** Current read position. */ + size_t read_pos = 0; + +public: + EndianBufferReader(span buffer) : buffer(buffer) {} + + void rewind() { this->read_pos = 0; } + + EndianBufferReader &operator >>(std::string &data) { data = this->ReadStr(); return *this; } + EndianBufferReader &operator >>(bool &data) { data = this->Read() != 0; return *this; } + + template + EndianBufferReader &operator >>(std::tuple &data) + { + this->ReadTuple(data, std::index_sequence_for{}); + return *this; + } + + template >, std::is_base_of>, int> = 0> + EndianBufferReader &operator >>(T &data) + { + if constexpr (std::is_enum_v) { + data = static_cast(this->Read>()); + } else if constexpr (std::is_base_of_v) { + data.value = this->Read(); + } else { + data = this->Read(); + } + return *this; + } + + template + static Tvalue ToValue(span buffer) + { + Tvalue result{}; + EndianBufferReader reader{ buffer }; + reader >> result; + return result; + } + +private: + /** Helper function to read a tuple from the buffer. */ + template + void ReadTuple(Ttuple &values, std::index_sequence) { + ((*this >> std::get(values)), ...); + } + + /** Read overload for string data. */ + std::string ReadStr() + { + std::string str; + while (this->read_pos < this->buffer.size()) { + char ch = this->Read(); + if (ch == '\0') break; + str.push_back(ch); + } + return str; + } + + /** Fundamental read function. */ + template + T Read() + { + static_assert(!std::is_const_v, "Can't read into const variables"); + static_assert(sizeof(T) <= 8, "Value can't be larger than 8 bytes"); + + if (read_pos + sizeof(T) > this->buffer.size()) return {}; + + T value = static_cast(this->buffer[this->read_pos++]); + if constexpr (sizeof(T) > 1) { + value += static_cast(this->buffer[this->read_pos++]) << 8; + } + if constexpr (sizeof(T) > 2) { + value += static_cast(this->buffer[this->read_pos++]) << 16; + value += static_cast(this->buffer[this->read_pos++]) << 24; + } + if constexpr (sizeof(T) > 4) { + value += static_cast(this->buffer[this->read_pos++]) << 32; + value += static_cast(this->buffer[this->read_pos++]) << 40; + value += static_cast(this->buffer[this->read_pos++]) << 48; + value += static_cast(this->buffer[this->read_pos++]) << 56; + } + + return value; + } +}; + +#endif /* ENDIAN_BUFFER_HPP */ diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index e106d5787f..ec0919757f 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -185,6 +185,17 @@ void Packet::Send_string(const std::string_view data) this->buffer.emplace_back('\0'); } +/** + * Copy a sized byte buffer into the packet. + * @param data The data to send. + */ +void Packet::Send_buffer(const std::vector &data) +{ + assert(this->CanWriteToPacket(sizeof(uint16) + data.size())); + this->Send_uint16((uint16)data.size()); + this->buffer.insert(this->buffer.end(), data.begin(), data.end()); +} + /** * Send as many of the bytes as possible in the packet. This can mean * that it is possible that not all bytes are sent. To cope with this @@ -366,6 +377,23 @@ uint64 Packet::Recv_uint64() return n; } +/** + * Extract a sized byte buffer from the packet. + * @return The extracted buffer. + */ +std::vector Packet::Recv_buffer() +{ + uint16 size = this->Recv_uint16(); + if (size == 0 || !this->CanReadFromPacket(size, true)) return {}; + + std::vector data; + while (size-- > 0) { + data.push_back(this->buffer[this->pos++]); + } + + return data; +} + /** * Reads characters (bytes) from the packet until it finds a '\0', or reaches a * maximum of \c length characters. diff --git a/src/network/core/packet.h b/src/network/core/packet.h index 277ff8bba1..04a232e1ca 100644 --- a/src/network/core/packet.h +++ b/src/network/core/packet.h @@ -72,6 +72,7 @@ public: void Send_uint32(uint32 data); void Send_uint64(uint64 data); void Send_string(const std::string_view data); + void Send_buffer(const std::vector &data); size_t Send_bytes (const byte *begin, const byte *end); /* Reading/receiving of packets */ @@ -87,6 +88,7 @@ public: uint16 Recv_uint16(); uint32 Recv_uint32(); uint64 Recv_uint64(); + std::vector Recv_buffer(); std::string Recv_string(size_t length, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); size_t RemainingBytesToTransfer() const; diff --git a/src/network/network.cpp b/src/network/network.cpp index 13f2fe52a4..8194f34d07 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -35,6 +35,7 @@ #include "../core/pool_func.hpp" #include "../gfx_func.h" #include "../error.h" +#include "../misc_cmd.h" #include #include #include @@ -1064,8 +1065,8 @@ void NetworkGameLoop() while (f != nullptr && !feof(f)) { if (_date == next_date && _date_fract == next_date_fract) { if (cp != nullptr) { - NetworkSendCommand(cp->cmd, cp->err_msg, nullptr, cp->company, cp->tile, cp->p1, cp->p2, cp->text); - Debug(desync, 0, "Injecting: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text, GetCommandName(cp->cmd)); + NetworkSendCommand(cp->cmd, cp->err_msg, nullptr, cp->company, cp->data); + Debug(desync, 0, "Injecting: {:08x}; {:02x}; {:02x}; {:08x}; {:06x}; {} ({})", _date, _date_fract, (int)_current_company, cp->cmd, cp->tile, FormatArrayAsHex(cp->data), GetCommandName(cp->cmd)); delete cp; cp = nullptr; } @@ -1104,15 +1105,21 @@ void NetworkGameLoop() cp = new CommandPacket(); int company; uint cmd; - char buffer[128]; - int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %x; %x; \"%127[^\"]\"", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cmd, &cp->err_msg, buffer); - cp->text = buffer; - /* There are 8 pieces of data to read, however the last is a - * string that might or might not exist. Ignore it if that - * string misses because in 99% of the time it's not used. */ - assert(ret == 9 || ret == 8); + char buffer[256]; + int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %255s", &next_date, &next_date_fract, &company, &cmd, &cp->err_msg, &cp->tile, buffer); + assert(ret == 6); cp->company = (CompanyID)company; cp->cmd = (Commands)cmd; + + /* Parse command data. */ + std::vector args; + size_t arg_len = strlen(buffer); + for (size_t i = 0; i + 1 < arg_len; i += 2) { + byte e = 0; + std::from_chars(buffer + i, buffer + i + 1, e, 16); + args.emplace_back(e); + } + cp->data = args; } else if (strncmp(p, "join: ", 6) == 0) { /* Manually insert a pause when joining; this way the client can join at the exact right time. */ int ret = sscanf(p + 6, "%x; %x", &next_date, &next_date_fract); @@ -1121,8 +1128,7 @@ void NetworkGameLoop() cp = new CommandPacket(); cp->company = COMPANY_SPECTATOR; cp->cmd = CMD_PAUSE; - cp->p1 = PM_PAUSED_NORMAL; - cp->p2 = 1; + cp->data = EndianBufferWriter<>::FromValue(CommandTraits::Args{ 0, PM_PAUSED_NORMAL, 1, "" }); _ddc_fastforward = false; } else if (strncmp(p, "sync: ", 6) == 0) { int ret = sscanf(p + 6, "%x; %x; %x; %x", &next_date, &next_date_fract, &sync_state[0], &sync_state[1]); diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 99f803e24e..4711cdf046 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -630,10 +630,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdLogging(ClientID clien p->Send_uint32(client_id); p->Send_uint8 (cp->company); p->Send_uint16(cp->cmd); - p->Send_uint32(cp->p1); - p->Send_uint32(cp->p2); - p->Send_uint32(cp->tile); - p->Send_string(cp->text); + p->Send_buffer(cp->data); p->Send_uint32(cp->frame); this->SendPacket(p); diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 0fae6bcbf0..472d5e60e2 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -15,18 +15,41 @@ #include "../company_func.h" #include "../settings_type.h" #include "../airport_cmd.h" +#include "../aircraft_cmd.h" +#include "../autoreplace_cmd.h" +#include "../company_cmd.h" #include "../depot_cmd.h" #include "../dock_cmd.h" +#include "../economy_cmd.h" +#include "../engine_cmd.h" +#include "../goal_cmd.h" #include "../group_cmd.h" #include "../industry_cmd.h" +#include "../landscape_cmd.h" +#include "../misc_cmd.h" +#include "../news_cmd.h" +#include "../object_cmd.h" +#include "../order_cmd.h" #include "../rail_cmd.h" #include "../road_cmd.h" +#include "../roadveh_cmd.h" +#include "../settings_cmd.h" +#include "../signs_cmd.h" +#include "../station_cmd.h" +#include "../story_cmd.h" +#include "../subsidy_cmd.h" #include "../terraform_cmd.h" +#include "../timetable_cmd.h" #include "../town_cmd.h" #include "../train_cmd.h" +#include "../tree_cmd.h" #include "../tunnelbridge_cmd.h" #include "../vehicle_cmd.h" +#include "../viewport_cmd.h" +#include "../water_cmd.h" +#include "../waypoint_cmd.h" #include "../script/script_cmd.h" +#include #include "../safeguards.h" @@ -62,6 +85,23 @@ static CommandCallback * const _callback_table[] = { /* 0x1B */ CcAddVehicleNewGroup, }; +/* Helpers to generate the command dispatch table from the command traits. */ + +template static CommandDataBuffer SanitizeCmdStrings(const CommandDataBuffer &data); +template static void UnpackNetworkCommand(const CommandPacket *cp); +struct CommandDispatch { + CommandDataBuffer(*Sanitize)(const CommandDataBuffer &); + void (*Unpack)(const CommandPacket *); +}; + +template +inline constexpr auto MakeDispatchTable(std::integer_sequence) noexcept +{ + return std::array{{ { &SanitizeCmdStrings(i)>, &UnpackNetworkCommand(i)> }... }}; +} +static constexpr auto _cmd_dispatch = MakeDispatchTable(std::make_integer_sequence, CMD_END>{}); + + /** * Append a CommandPacket at the end of the queue. * @param p The packet to append to the queue. @@ -148,16 +188,29 @@ static CommandQueue _local_execution_queue; * @param text The text to pass */ void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +{ + auto data = EndianBufferWriter::FromValue(std::make_tuple(tile, p1, p2, text)); + NetworkSendCommand(cmd, err_message, callback, company, tile, data); +} + +/** + * Prepare a DoCommand to be send over the network + * @param cmd The command to execute (a CMD_* value) + * @param err_message Message prefix to show on error + * @param callback A callback function to call after the command is finished + * @param company The company that wants to send the command + * @param location Location of the command (e.g. for error message position) + * @param cmd_data The command proc arguments. + */ +void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex location, const CommandDataBuffer &cmd_data) { CommandPacket c; c.company = company; - c.tile = tile; - c.p1 = p1; - c.p2 = p2; c.cmd = cmd; c.err_msg = err_message; c.callback = callback; - c.text = text; + c.tile = location; + c.data = cmd_data; if (_network_server) { /* If we are the server, we queue the command in our 'special' queue. @@ -220,7 +273,7 @@ void NetworkExecuteLocalCommandQueue() /* We can execute this command */ _current_company = cp->company; - DoCommandP(cp, cp->my_cmd, true); + _cmd_dispatch[cp->cmd].Unpack(cp); queue.Pop(); delete cp; @@ -311,11 +364,8 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c if (!IsValidCommand(cp->cmd)) return "invalid command"; if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "single-player only command"; cp->err_msg = p->Recv_uint16(); - - cp->p1 = p->Recv_uint32(); - cp->p2 = p->Recv_uint32(); cp->tile = p->Recv_uint32(); - cp->text = p->Recv_string(NETWORK_COMPANY_NAME_LENGTH, (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK); + cp->data = _cmd_dispatch[cp->cmd].Sanitize(p->Recv_buffer()); byte callback = p->Recv_uint8(); if (callback >= lengthof(_callback_table)) return "invalid callback"; @@ -331,13 +381,11 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c */ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp) { - p->Send_uint8 (cp->company); + p->Send_uint8(cp->company); p->Send_uint16(cp->cmd); p->Send_uint16(cp->err_msg); - p->Send_uint32(cp->p1); - p->Send_uint32(cp->p2); p->Send_uint32(cp->tile); - p->Send_string(cp->text); + p->Send_buffer(cp->data); byte callback = 0; while (callback < lengthof(_callback_table) && _callback_table[callback] != cp->callback) { @@ -350,3 +398,58 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp) } p->Send_uint8 (callback); } + +/** + * Insert a client ID into the command data in a command packet. + * @param cp Command packet to modify. + * @param client_id Client id to insert. + */ +void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id) +{ + /* Unpack command parameters. */ + auto params = EndianBufferReader::ToValue>(cp.data); + + /* Insert client id. */ + std::get<2>(params) = client_id; + + /* Repack command parameters. */ + cp.data = EndianBufferWriter::FromValue(params); +} + + +/** Validate a single string argument coming from network. */ +template +static inline void SanitizeSingleStringHelper([[maybe_unused]] CommandFlags cmd_flags, T &data) +{ + if constexpr (std::is_same_v) { + data = StrMakeValid(data.substr(0, NETWORK_COMPANY_NAME_LENGTH), (!_network_server && cmd_flags & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK); + } +} + +/** Helper function to perform validation on command data strings. */ +template +static inline void SanitizeStringsHelper(CommandFlags cmd_flags, Ttuple &values, std::index_sequence) +{ + ((SanitizeSingleStringHelper(cmd_flags, std::get(values))), ...); +} + +/** + * Validate and sanitize strings in command data. + * @tparam Tcmd Command this data belongs to. + * @param data Command data. + * @return Sanitized command data. + */ +template +CommandDataBuffer SanitizeCmdStrings(const CommandDataBuffer &data) +{ + auto args = EndianBufferReader::ToValue::Args>(data); + SanitizeStringsHelper(CommandTraits::flags, args, std::make_index_sequence::Args>>{}); + return EndianBufferWriter::FromValue(args); +} + +template +void UnpackNetworkCommand(const CommandPacket *cp) +{ + auto args = EndianBufferReader::ToValue::Args>(cp->data); + std::apply(&InjectNetworkCommand, std::tuple_cat(std::make_tuple(Tcmd, cp->err_msg, cp->callback, cp->my_cmd), args)); +} diff --git a/src/network/network_internal.h b/src/network/network_internal.h index 25240da5d7..58c99867c2 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -15,6 +15,8 @@ #include "core/tcp_game.h" #include "../command_type.h" +#include "../command_func.h" +#include "../misc/endian_buffer.hpp" #ifdef RANDOM_DEBUG /** @@ -104,19 +106,26 @@ void UpdateNetworkGameWindow(); /** * Everything we need to know about a command to be able to execute it. */ -struct CommandPacket : CommandContainer { +struct CommandPacket { /** Make sure the pointer is nullptr. */ - CommandPacket() : next(nullptr), company(INVALID_COMPANY), frame(0), my_cmd(false) {} + CommandPacket() : next(nullptr), company(INVALID_COMPANY), frame(0), my_cmd(false), tile(0) {} CommandPacket *next; ///< the next command packet (if in queue) CompanyID company; ///< company that is executing the command uint32 frame; ///< the frame in which this packet is executed bool my_cmd; ///< did the command originate from "me" + + Commands cmd; ///< command being executed. + StringID err_msg; ///< string ID of error message to use. + CommandCallback *callback; ///< any callback function executed upon successful completion of the command. + TileIndex tile; ///< location of the command (for e.g. error message or effect display). + CommandDataBuffer data; ///< command parameters. }; void NetworkDistributeCommands(); void NetworkExecuteLocalCommandQueue(); void NetworkFreeLocalCommandQueue(); void NetworkSyncCommandQueue(NetworkClientSocket *cs); +void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id); void ShowNetworkError(StringID error_string); void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const std::string &name, const std::string &str = "", int64 data = 0, const std::string &data_str = ""); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 50b46dfe10..967ad40a89 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -24,6 +24,7 @@ #include "../genworld.h" #include "../company_func.h" #include "../company_gui.h" +#include "../company_cmd.h" #include "../roadveh.h" #include "../order_backup.h" #include "../core/pool_func.hpp" @@ -1048,14 +1049,15 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet * to match the company in the packet. If it doesn't, the client has done * something pretty naughty (or a bug), and will be kicked */ - if (!(cp.cmd == CMD_COMPANY_CTRL && cp.p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) { + uint32 company_p1 = cp.cmd == CMD_COMPANY_CTRL ? std::get<1>(EndianBufferReader::ToValue::Args>(cp.data)) : 0; + if (!(cp.cmd == CMD_COMPANY_CTRL && company_p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) { IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a command as another company {}.", ci->client_playas + 1, this->GetClientIP(), cp.company + 1); return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH); } if (cp.cmd == CMD_COMPANY_CTRL) { - if (cp.p1 != 0 || cp.company != COMPANY_SPECTATOR) { + if (company_p1 != 0 || cp.company != COMPANY_SPECTATOR) { return this->SendError(NETWORK_ERROR_CHEATER); } @@ -1066,7 +1068,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet } } - if (GetCommandFlags(cp.cmd) & CMD_CLIENT_ID) cp.p2 = this->client_id; + if (GetCommandFlags(cp.cmd) & CMD_CLIENT_ID) NetworkReplaceCommandClientId(cp, this->client_id); this->incoming_queue.Append(&cp); return NETWORK_RECV_STATUS_OKAY; diff --git a/src/string.cpp b/src/string.cpp index d027cb7bff..aeac4fe84f 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -19,6 +19,7 @@ #include #include /* required for tolower() */ #include +#include #ifdef _MSC_VER #include // required by vsnprintf implementation for MSVC @@ -160,6 +161,23 @@ char *CDECL str_fmt(const char *str, ...) return p; } +/** + * Format a byte array into a continuous hex string. + * @param data Array to format + * @return Converted string. + */ +std::string FormatArrayAsHex(span data) +{ + std::ostringstream ss; + ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex; + + for (auto b : data) { + ss << b; + } + + return ss.str(); +} + /** * Scan the string for old values of SCC_ENCODED and fix it to * it's new, static value. diff --git a/src/string_func.h b/src/string_func.h index 0cbf26d6b2..a5d3499c76 100644 --- a/src/string_func.h +++ b/src/string_func.h @@ -28,6 +28,7 @@ #include #include "core/bitmath_func.hpp" +#include "core/span_type.hpp" #include "string_type.h" char *strecat(char *dst, const char *src, const char *last) NOACCESS(3); @@ -39,6 +40,8 @@ int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap) char *CDECL str_fmt(const char *str, ...) WARN_FORMAT(1, 2); +std::string FormatArrayAsHex(span data); + void StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) NOACCESS(2); [[nodiscard]] std::string StrMakeValid(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); void StrMakeValidInPlace(char *str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); From 996b16de707c449a83676c614edbd5a81d37b253 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Fri, 29 Oct 2021 00:56:07 +0200 Subject: [PATCH 13/60] Codechange: Use lambdas instead of CommandContainer to manage station picker commands. --- src/airport_gui.cpp | 17 +++++++++++++++-- src/command.cpp | 26 -------------------------- src/command_func.h | 2 -- src/command_type.h | 13 ------------- src/dock_gui.cpp | 22 ++++++++++++++++------ src/rail_gui.cpp | 44 ++++++++++++++++++++++++++++++++++++++------ src/road_gui.cpp | 26 +++++++++++++++++++------- src/station_gui.cpp | 36 ++++++++++++++++-------------------- src/station_gui.h | 8 ++++++-- 9 files changed, 110 insertions(+), 84 deletions(-) diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 41fde9b8ce..65c59784b5 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -26,7 +26,9 @@ #include "hotkeys.h" #include "vehicle_func.h" #include "gui.h" +#include "command_func.h" #include "airport_cmd.h" +#include "station_cmd.h" #include "widgets/airport_widget.h" @@ -61,8 +63,19 @@ static void PlaceAirport(TileIndex tile) uint32 p1 = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex(); p1 |= _selected_airport_layout << 8; - CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_AIRPORT, STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, "" }; - ShowSelectStationIfNeeded(cmdcont, TileArea(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE)); + + auto proc = [=](bool test, StationID to_join) -> bool { + if (test) { + return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_AIRPORT)), CMD_BUILD_AIRPORT, tile, p1, p2).Succeeded(); + } else { + uint32 p2_final = p2; + if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); + + return DoCommandP(CMD_BUILD_AIRPORT, STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, tile, p1, p2_final); + } + }; + + ShowSelectStationIfNeeded(TileArea(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE), proc); } /** Airport build toolbar window handler. */ diff --git a/src/command.cpp b/src/command.cpp index 788c71989c..e9ae695285 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -163,20 +163,6 @@ bool IsCommandAllowedWhilePaused(Commands cmd) static int _docommand_recursive = 0; - -/** - * Shorthand for calling the long DoCommand with a container. - * - * @param container Container with (almost) all information - * @param flags Flags for the command and how to execute the command - * @see CommandProc - * @return the cost - */ -CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags) -{ - return DoCommand(flags, container->cmd, container->tile, container->p1, container->p2, container->text); -} - /*! * This function executes a given command with the parameters from the #CommandProc parameter list. * Depending on the flags parameter it execute or test a command. @@ -326,18 +312,6 @@ static bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *call return res.Succeeded(); } -/** - * Shortcut for the long DoCommandP when having a container with the data. - * @param container the container with information. - * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) - * @param network_command execute the command without sending it on the network - * @return true if the command succeeded, else false - */ -bool DoCommandP(const CommandContainer *container, bool my_cmd, bool network_command) -{ - return DoCommandP(container->cmd, container->err_msg, container->callback, my_cmd, network_command, container->tile, container->p1, container->p2, container->text); -} - /** * Shortcut for the long DoCommandP when not using a callback or error message. * @param cmd The command to execute (a CMD_* value) diff --git a/src/command_func.h b/src/command_func.h index 0d000755c8..0b539746d9 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -37,13 +37,11 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); typedef std::vector CommandDataBuffer; CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags); bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); bool DoCommandP(Commands cmd, StringID err_message, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); bool DoCommandP(Commands cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); bool DoCommandP(Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -bool DoCommandP(const CommandContainer *container, bool my_cmd = true, bool network_command = false); bool InjectNetworkCommand(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); diff --git a/src/command_type.h b/src/command_type.h index 3a15087b9a..cc5e97795e 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -460,17 +460,4 @@ template struct CommandTraits; */ typedef void CommandCallback(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); -/** - * Structure for buffering the build command when selecting a station to join. - */ -struct CommandContainer { - TileIndex tile; ///< tile command being executed on. - uint32 p1; ///< parameter p1. - uint32 p2; ///< parameter p2. - Commands cmd; ///< command being executed. - StringID err_msg; ///< string ID of error message to use. - CommandCallback *callback; ///< any callback function executed upon successful completion of the command. - std::string text; ///< possible text sent for name changes etc. -}; - #endif /* COMMAND_TYPE_H */ diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 52b1483815..da7e0518f4 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -27,6 +27,7 @@ #include "zoom_func.h" #include "tunnelbridge_cmd.h" #include "dock_cmd.h" +#include "station_cmd.h" #include "widgets/dock_widget.h" @@ -205,16 +206,25 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_STATION: { // Build station button - uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join - - /* tile is always the land tile, so need to evaluate _thd.pos */ - CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK, STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, "" }; - /* Determine the watery part of the dock. */ DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile); - ShowSelectStationIfNeeded(cmdcont, TileArea(tile, tile_to)); + uint32 p1 = _ctrl_pressed; + uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join + + auto proc = [=](bool test, StationID to_join) -> bool { + if (test) { + return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_DOCK)), CMD_BUILD_DOCK, tile, p1, p2).Succeeded(); + } else { + uint32 p2_final = p2; + if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); + + return DoCommandP(CMD_BUILD_DOCK, STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, tile, p1, p2_final); + } + }; + + ShowSelectStationIfNeeded(TileArea(tile, tile_to), proc); break; } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 7cf1b0059f..76d51ccb2c 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -36,6 +36,8 @@ #include "sortlist_type.h" #include "stringfilter_type.h" #include "string_func.h" +#include "station_cmd.h" +#include "waypoint_cmd.h" #include "station_map.h" #include "tunnelbridge_map.h" @@ -198,8 +200,18 @@ static void PlaceRail_Station(TileIndex tile) int h = _settings_client.gui.station_platlength; if (!_railstation.orientation) Swap(w, h); - CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, "" }; - ShowSelectStationIfNeeded(cmdcont, TileArea(tile, w, h)); + auto proc = [=](bool test, StationID to_join) -> bool { + if (test) { + return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_RAIL_STATION)), CMD_BUILD_RAIL_STATION, tile, p1, p2).Succeeded(); + } else { + uint32 p2_final = p2; + if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); + + return DoCommandP(CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, tile, p1, p2_final); + } + }; + + ShowSelectStationIfNeeded(TileArea(tile, w, h), proc); } } @@ -724,8 +736,18 @@ struct BuildRailToolbarWindow : Window { uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 6 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24; uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16; - CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, "" }; - ShowSelectWaypointIfNeeded(cmdcont, ta); + auto proc = [=](bool test, StationID to_join) -> bool { + if (test) { + return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_RAIL_WAYPOINT)), CMD_BUILD_RAIL_WAYPOINT, ta.tile, p1, p2).Succeeded(); + } else { + uint32 p2_final = p2; + if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); + + return DoCommandP(CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, ta.tile, p1, p2_final); + } + }; + + ShowSelectWaypointIfNeeded(ta, proc); } } break; @@ -883,8 +905,18 @@ static void HandleStationPlacement(TileIndex start, TileIndex end) uint32 p1 = _cur_railtype | _railstation.orientation << 6 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24; uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16; - CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, "" }; - ShowSelectStationIfNeeded(cmdcont, ta); + auto proc = [=](bool test, StationID to_join) -> bool { + if (test) { + return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_RAIL_STATION)), CMD_BUILD_RAIL_STATION, ta.tile, p1, p2).Succeeded(); + } else { + uint32 p2_final = p2; + if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); + + return DoCommandP(CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, ta.tile, p1, p2_final); + } + }; + + ShowSelectStationIfNeeded(ta, proc); } /** Enum referring to the Hotkeys in the build rail station window */ diff --git a/src/road_gui.cpp b/src/road_gui.cpp index eedcc8f59c..00ea29042d 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -31,6 +31,7 @@ #include "strings_func.h" #include "core/geometry_func.hpp" #include "date_func.h" +#include "station_cmd.h" #include "widgets/road_widget.h" @@ -179,12 +180,14 @@ void CcRoadStop(const CommandCost &result, Commands cmd, TileIndex tile, uint32 * @param p2 bit 0: 0 For bus stops, 1 for truck stops. * bit 2: Allow stations directly adjacent to other stations. * bit 5..10: The roadtypes. - * @param cmd Command to use. * @param err_msg Error message to show. * @see CcRoadStop() */ -static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, Commands cmd, StringID err_msg) +static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, StringID err_msg) { + TileArea ta(start_tile, end_tile); + uint32 p1 = (uint32)(ta.w | ta.h << 8); + uint8 ddir = _road_station_picker_orientation; SB(p2, 16, 16, INVALID_STATION); // no station to join @@ -194,9 +197,18 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, C } p2 |= ddir << 3; // Set the DiagDirecion into p2 bits 3 and 4. - TileArea ta(start_tile, end_tile); - CommandContainer cmdcont = { ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, err_msg, CcRoadStop, "" }; - ShowSelectStationIfNeeded(cmdcont, ta); + auto proc = [=](bool test, StationID to_join) -> bool { + if (test) { + return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_ROAD_STOP)), CMD_BUILD_ROAD_STOP, ta.tile, p1, p2).Succeeded(); + } else { + uint32 p2_final = p2; + if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); + + return DoCommandP(CMD_BUILD_ROAD_STOP, err_msg, CcRoadStop, ta.tile, p1, p2_final); + } + }; + + ShowSelectStationIfNeeded(ta, proc); } /** @@ -684,7 +696,7 @@ struct BuildRoadToolbarWindow : Window { TileArea ta(start_tile, end_tile); DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS); } else { - PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP, this->rti->strings.err_build_station[ROADSTOP_BUS]); + PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, this->rti->strings.err_build_station[ROADSTOP_BUS]); } } break; @@ -696,7 +708,7 @@ struct BuildRoadToolbarWindow : Window { TileArea ta(start_tile, end_tile); DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK); } else { - PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP, this->rti->strings.err_build_station[ROADSTOP_TRUCK]); + PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, this->rti->strings.err_build_station[ROADSTOP_TRUCK]); } } break; diff --git a/src/station_gui.cpp b/src/station_gui.cpp index e1229fe3d1..2e04e7ac44 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -2264,13 +2264,13 @@ static const NWidgetPart _nested_select_station_widgets[] = { */ template struct SelectStationWindow : Window { - CommandContainer select_station_cmd; ///< Command to build new station + StationPickerCmdProc select_station_proc; TileArea area; ///< Location of new station Scrollbar *vscroll; - SelectStationWindow(WindowDesc *desc, const CommandContainer &cmd, TileArea ta) : + SelectStationWindow(WindowDesc *desc, TileArea ta, StationPickerCmdProc&& proc) : Window(desc), - select_station_cmd(cmd), + select_station_proc(std::move(proc)), area(ta) { this->CreateNestedTree(); @@ -2341,12 +2341,8 @@ struct SelectStationWindow : Window { if (distant_join && st_index >= _stations_nearby_list.size()) return; - /* Insert station to be joined into stored command */ - SB(this->select_station_cmd.p2, 16, 16, - (distant_join ? _stations_nearby_list[st_index] : NEW_STATION)); - /* Execute stored Command */ - DoCommandP(&this->select_station_cmd); + this->select_station_proc(false, distant_join ? _stations_nearby_list[st_index] : NEW_STATION); /* Close Window; this might cause double frees! */ CloseWindowById(WC_SELECT_STATION, 0); @@ -2412,7 +2408,7 @@ static WindowDesc _select_station_desc( * @return whether we need to show the station selection window. */ template -static bool StationJoinerNeeded(const CommandContainer &cmd, TileArea ta) +static bool StationJoinerNeeded(TileArea ta, const StationPickerCmdProc &proc) { /* Only show selection if distant join is enabled in the settings */ if (!_settings_game.station.distant_join_stations) return false; @@ -2430,7 +2426,7 @@ static bool StationJoinerNeeded(const CommandContainer &cmd, TileArea ta) if (!_ctrl_pressed) return false; /* Now check if we could build there */ - if (DoCommand(&cmd, CommandFlagsToDCFlags(GetCommandFlags(cmd.cmd))).Failed()) return false; + if (!proc(true, INVALID_STATION)) return false; /* Test for adjacent station or station below selection. * If adjacent-stations is disabled and we are building next to a station, do not show the selection window. @@ -2446,32 +2442,32 @@ static bool StationJoinerNeeded(const CommandContainer &cmd, TileArea ta) * @tparam the class to find stations for */ template -void ShowSelectBaseStationIfNeeded(const CommandContainer &cmd, TileArea ta) +void ShowSelectBaseStationIfNeeded(TileArea ta, StationPickerCmdProc&& proc) { - if (StationJoinerNeeded(cmd, ta)) { + if (StationJoinerNeeded(ta, proc)) { if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - new SelectStationWindow(&_select_station_desc, cmd, ta); + new SelectStationWindow(&_select_station_desc, ta, std::move(proc)); } else { - DoCommandP(&cmd); + proc(false, INVALID_STATION); } } /** * Show the station selection window when needed. If not, build the station. - * @param cmd Command to build the station. * @param ta Area to build the station in + * @param proc Function called to execute the build command. */ -void ShowSelectStationIfNeeded(const CommandContainer &cmd, TileArea ta) +void ShowSelectStationIfNeeded(TileArea ta, StationPickerCmdProc proc) { - ShowSelectBaseStationIfNeeded(cmd, ta); + ShowSelectBaseStationIfNeeded(ta, std::move(proc)); } /** * Show the waypoint selection window when needed. If not, build the waypoint. - * @param cmd Command to build the waypoint. * @param ta Area to build the waypoint in + * @param proc Function called to execute the build command. */ -void ShowSelectWaypointIfNeeded(const CommandContainer &cmd, TileArea ta) +void ShowSelectWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc) { - ShowSelectBaseStationIfNeeded(cmd, ta); + ShowSelectBaseStationIfNeeded(ta, std::move(proc)); } diff --git a/src/station_gui.h b/src/station_gui.h index ac2fa2fc32..9bed30b672 100644 --- a/src/station_gui.h +++ b/src/station_gui.h @@ -13,6 +13,8 @@ #include "command_type.h" #include "tilearea_type.h" #include "window_type.h" +#include "station_type.h" +#include /** Types of cargo to display for station coverage. */ @@ -25,7 +27,9 @@ enum StationCoverageType { int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageType sct, int rad, bool supplies); void CheckRedrawStationCoverage(const Window *w); -void ShowSelectStationIfNeeded(const CommandContainer &cmd, TileArea ta); -void ShowSelectWaypointIfNeeded(const CommandContainer &cmd, TileArea ta); +using StationPickerCmdProc = std::function; + +void ShowSelectStationIfNeeded(TileArea ta, StationPickerCmdProc proc); +void ShowSelectWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc); #endif /* STATION_GUI_H */ From c88b104ec662ea80bec89f58aa7ad9d0baac7704 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Fri, 29 Oct 2021 14:41:20 +0200 Subject: [PATCH 14/60] Codechange: Use wrapper struct to automatically manage command depth tracking. --- src/command.cpp | 59 ++++++++++++++++++---------------------------- src/command_func.h | 11 +++++++++ 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index e9ae695285..06025a949d 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -65,6 +65,9 @@ #include "safeguards.h" +int RecursiveCommandCounter::_counter = 0; + + /** * Define a command with the flags which belongs to it. * @@ -162,7 +165,6 @@ bool IsCommandAllowedWhilePaused(Commands cmd) } -static int _docommand_recursive = 0; /*! * This function executes a given command with the parameters from the #CommandProc parameter list. * Depending on the flags parameter it execute or test a command. @@ -186,43 +188,34 @@ CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 /* Chop of any CMD_MSG or other flags; we don't need those here */ CommandProc *proc = _command_proc_table[cmd].proc; - _docommand_recursive++; + RecursiveCommandCounter counter{}; /* only execute the test call if it's toplevel, or we're not execing. */ - if (_docommand_recursive == 1 || !(flags & DC_EXEC) ) { - if (_docommand_recursive == 1) _cleared_object_areas.clear(); + if (counter.IsTopLevel() || !(flags & DC_EXEC) ) { + if (counter.IsTopLevel()) _cleared_object_areas.clear(); SetTownRatingTestMode(true); res = proc(flags & ~DC_EXEC, tile, p1, p2, text); SetTownRatingTestMode(false); - if (res.Failed()) { - goto error; - } + if (res.Failed()) return res; - if (_docommand_recursive == 1 && + if (counter.IsTopLevel() && !(flags & DC_QUERY_COST) && !(flags & DC_BANKRUPT) && !CheckCompanyHasMoney(res)) { // CheckCompanyHasMoney() modifies 'res' to an error if it fails. - goto error; - } - - if (!(flags & DC_EXEC)) { - _docommand_recursive--; return res; } + + if (!(flags & DC_EXEC)) return res; } /* Execute the command here. All cost-relevant functions set the expenses type * themselves to the cost object at some point */ - if (_docommand_recursive == 1) _cleared_object_areas.clear(); + if (counter.IsTopLevel()) _cleared_object_areas.clear(); res = proc(flags, tile, p1, p2, text); - if (res.Failed()) { -error: - _docommand_recursive--; - return res; - } + if (res.Failed()) return res; /* if toplevel, subtract the money. */ - if (--_docommand_recursive == 0 && !(flags & DC_BANKRUPT)) { + if (counter.IsTopLevel() && !(flags & DC_BANKRUPT)) { SubtractMoneyFromCompany(res); } @@ -395,12 +388,6 @@ bool InjectNetworkCommand(Commands cmd, StringID err_message, CommandCallback *c return DoCommandP(cmd, err_message, callback, my_cmd, true, tile, p1, p2, text); } -/** - * Helper to deduplicate the code for returning. - * @param cmd the command cost to return. - */ -#define return_dcpi(cmd) { _docommand_recursive = 0; return cmd; } - /** Helper to format command parameters into a hex string. */ static std::string CommandParametersToHexString(TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { @@ -423,9 +410,10 @@ static std::string CommandParametersToHexString(TileIndex tile, uint32 p1, uint3 */ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) { + RecursiveCommandCounter counter{}; + /* Prevent recursion; it gives a mess over the network */ - assert(_docommand_recursive == 0); - _docommand_recursive = 1; + assert(counter.IsTopLevel()); /* Reset the state. */ _additional_cash_required = 0; @@ -446,7 +434,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba assert(!(cmd_flags & CMD_CLIENT_ID) || p2 != 0); /* Do not even think about executing out-of-bounds tile-commands */ - if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (cmd_flags & CMD_ALL_TILES) == 0))) return_dcpi(CMD_ERROR); + if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (cmd_flags & CMD_ALL_TILES) == 0))) return CMD_ERROR; /* Always execute server and spectator commands as spectator */ bool exec_as_spectator = (cmd_flags & (CMD_SPECTATOR | CMD_SERVER)) != 0; @@ -455,7 +443,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba * The server will ditch any server commands a client sends to it, so effectively * this guards the server from executing functions for an invalid company. */ if (_game_mode == GM_NORMAL && !exec_as_spectator && !Company::IsValidID(_current_company) && !(_current_company == OWNER_DEITY && (cmd_flags & CMD_DEITY) != 0)) { - return_dcpi(CMD_ERROR); + return CMD_ERROR; } Backup cur_company(_current_company, FILE_LINE); @@ -487,7 +475,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba Debug(desync, 1, "cmdf: {:08x}; {:02x}; {:02x}; {:08x}; {:08x}; {:06x}; {} ({})", _date, _date_fract, (int)_current_company, cmd, err_message, tile, CommandParametersToHexString(tile, p1, p2, text), GetCommandName(cmd)); } cur_company.Restore(); - return_dcpi(res); + return res; } /* @@ -502,7 +490,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba * This way it's not handled by DoCommand and only the * actual execution of the command causes messages. Also * reset the storages as we've not executed the command. */ - return_dcpi(CommandCost()); + return CommandCost(); } Debug(desync, 1, "cmd: {:08x}; {:02x}; {:02x}; {:08x}; {:08x}; {:06x}; {} ({})", _date, _date_fract, (int)_current_company, cmd, err_message, tile, CommandParametersToHexString(tile, p1, p2, text), GetCommandName(cmd)); @@ -532,7 +520,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba if (!test_and_exec_can_differ) { assert(res.GetCost() == res2.GetCost() && res.Failed() == res2.Failed()); // sanity check } else if (res2.Failed()) { - return_dcpi(res2); + return res2; } /* If we're needing more money and we haven't done @@ -542,7 +530,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba * So make sure the signal buffer is empty even in this case */ UpdateSignalsInBuffer(); SetDParam(0, _additional_cash_required); - return_dcpi(CommandCost(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY)); + return CommandCost(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY); } /* update last build coordinate of company. */ @@ -556,9 +544,8 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba /* update signals if needed */ UpdateSignalsInBuffer(); - return_dcpi(res2); + return res2; } -#undef return_dcpi /** diff --git a/src/command_func.h b/src/command_func.h index 0b539746d9..2a6f0c68a7 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -72,4 +72,15 @@ static inline DoCommandFlag CommandFlagsToDCFlags(CommandFlags cmd_flags) return flags; } +/** Helper class to keep track of command nesting level. */ +struct RecursiveCommandCounter { + RecursiveCommandCounter() noexcept { _counter++; } + ~RecursiveCommandCounter() noexcept { _counter--; } + + /** Are we in the top-level command execution? */ + bool IsTopLevel() const { return _counter == 1; } +private: + static int _counter; +}; + #endif /* COMMAND_FUNC_H */ From e740c24eb7a90bc771f5976d64d80639ee7576e5 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sat, 30 Oct 2021 01:31:46 +0200 Subject: [PATCH 15/60] Codechange: Template DoCommand to automagically reflect the parameters of the command proc. When finished, this will allow each command handler to take individually different parameters, obliviating the need for bit-packing. --- src/aircraft_cmd.cpp | 7 ++- src/airport_gui.cpp | 2 +- src/autoreplace_cmd.cpp | 32 ++++++----- src/bridge_gui.cpp | 3 +- src/build_vehicle_gui.cpp | 2 +- src/clear_cmd.cpp | 3 +- src/command.cpp | 92 ++++++++++++------------------- src/command_func.h | 73 +++++++++++++++++++++++- src/command_type.h | 3 +- src/company_cmd.cpp | 2 +- src/disaster_vehicle.cpp | 5 +- src/dock_gui.cpp | 2 +- src/economy.cpp | 11 ++-- src/group_cmd.cpp | 8 +-- src/industry_cmd.cpp | 16 +++--- src/landscape.cpp | 4 +- src/misc_gui.cpp | 3 +- src/object_cmd.cpp | 13 +++-- src/order_backup.cpp | 5 +- src/order_cmd.cpp | 3 +- src/rail_cmd.cpp | 27 +++++---- src/rail_gui.cpp | 9 +-- src/road_cmd.cpp | 22 ++++---- src/road_gui.cpp | 5 +- src/roadveh_cmd.cpp | 3 +- src/script/api/script_object.cpp | 2 +- src/script/api/script_vehicle.cpp | 5 +- src/station_cmd.cpp | 24 ++++---- src/terraform_cmd.cpp | 7 ++- src/terraform_gui.cpp | 3 +- src/town_cmd.cpp | 50 +++++++++-------- src/train_cmd.cpp | 4 +- src/tree_cmd.cpp | 5 +- src/tunnelbridge_cmd.cpp | 18 +++--- src/vehicle.cpp | 12 ++-- src/vehicle_cmd.cpp | 33 ++++++----- src/vehicle_gui.cpp | 5 +- src/water_cmd.cpp | 23 ++++---- src/waypoint_cmd.cpp | 3 +- 39 files changed, 320 insertions(+), 229 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 5e0eea35bf..998f75e6bd 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -38,6 +38,7 @@ #include "newgrf_airporttiles.h" #include "framerate_type.h" #include "aircraft_cmd.h" +#include "vehicle_cmd.h" #include "table/strings.h" @@ -1275,7 +1276,7 @@ void HandleMissingAircraftOrders(Aircraft *v) const Station *st = GetTargetAirportIfValid(v); if (st == nullptr) { Backup cur_company(_current_company, v->owner, FILE_LINE); - CommandCost ret = DoCommand(DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT, v->tile, v->index, 0); + CommandCost ret = Command::Do(DC_EXEC, v->tile, v->index, 0, {}); cur_company.Restore(); if (ret.Failed()) CrashAirplane(v); @@ -1638,7 +1639,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass /* Send the helicopter to a hangar if needed for replacement */ if (v->NeedsAutomaticServicing()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - DoCommand(DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT, v->tile, v->index | DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, 0); + Command::Do(DC_EXEC, v->tile, v->index | DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, 0, {}); cur_company.Restore(); } } @@ -1689,7 +1690,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc /* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */ if (v->NeedsAutomaticServicing()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - DoCommand(DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT, v->tile, v->index | DEPOT_SERVICE, 0); + Command::Do(DC_EXEC, v->tile, v->index | DEPOT_SERVICE, 0, {}); cur_company.Restore(); } } diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 65c59784b5..98776e52fd 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -66,7 +66,7 @@ static void PlaceAirport(TileIndex tile) auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_AIRPORT)), CMD_BUILD_AIRPORT, tile, p1, p2).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, p1, p2, {}).Succeeded(); } else { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index a4a4e88a2f..4ba41942c9 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -23,6 +23,10 @@ #include "news_func.h" #include "strings_func.h" #include "autoreplace_cmd.h" +#include "group_cmd.h" +#include "order_cmd.h" +#include "train_cmd.h" +#include "vehicle_cmd.h" #include "table/strings.h" @@ -341,7 +345,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic } /* Build the new vehicle */ - cost = DoCommand(DC_EXEC | DC_AUTOREPLACE, CMD_BUILD_VEHICLE, old_veh->tile, e | (CT_INVALID << 24), 0); + cost = Command::Do(DC_EXEC | DC_AUTOREPLACE, old_veh->tile, e | (CT_INVALID << 24), 0, {}); if (cost.Failed()) return cost; Vehicle *new_veh = Vehicle::Get(_new_vehicle_id); @@ -351,13 +355,13 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic if (refit_cargo != CT_NO_REFIT) { byte subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo); - cost.AddCost(DoCommand(DC_EXEC, CMD_REFIT_VEHICLE, 0, new_veh->index, refit_cargo | (subtype << 8))); + cost.AddCost(Command::Do(DC_EXEC, 0, new_veh->index, refit_cargo | (subtype << 8), {})); assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace() } /* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */ if (new_veh->type == VEH_TRAIN && HasBit(Train::From(old_veh)->flags, VRF_REVERSE_DIRECTION)) { - DoCommand(DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION, 0, new_veh->index, true); + Command::Do(DC_EXEC, 0, new_veh->index, true, {}); } return cost; @@ -371,7 +375,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic */ static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_callback) { - return DoCommand(DC_EXEC | DC_AUTOREPLACE, CMD_START_STOP_VEHICLE, 0, v->index, evaluate_callback ? 1 : 0); + return Command::Do(DC_EXEC | DC_AUTOREPLACE, 0, v->index, evaluate_callback ? 1 : 0, {}); } /** @@ -384,7 +388,7 @@ static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_ca */ static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlag flags, bool whole_chain) { - return DoCommand(flags | DC_NO_CARGO_CAP_CHECK, CMD_MOVE_RAIL_VEHICLE, 0, v->index | (whole_chain ? 1 : 0) << 20, after != nullptr ? after->index : INVALID_VEHICLE); + return Command::Do(flags | DC_NO_CARGO_CAP_CHECK, 0, v->index | (whole_chain ? 1 : 0) << 20, after != nullptr ? after->index : INVALID_VEHICLE, {}); } /** @@ -398,10 +402,10 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, CommandCost cost = CommandCost(); /* Share orders */ - if (cost.Succeeded() && old_head != new_head) cost.AddCost(DoCommand(DC_EXEC, CMD_CLONE_ORDER, 0, new_head->index | CO_SHARE << 30, old_head->index)); + if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command::Do(DC_EXEC, 0, new_head->index | CO_SHARE << 30, old_head->index, {})); /* Copy group membership */ - if (cost.Succeeded() && old_head != new_head) cost.AddCost(DoCommand(DC_EXEC, CMD_ADD_VEHICLE_GROUP, 0, old_head->group_id, new_head->index)); + if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command::Do(DC_EXEC, 0, old_head->group_id, new_head->index, {})); /* Perform start/stop check whether the new vehicle suits newgrf restrictions etc. */ if (cost.Succeeded()) { @@ -467,11 +471,11 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b } /* Sell the old vehicle */ - cost.AddCost(DoCommand(flags, CMD_SELL_VEHICLE, 0, old_v->index, 0)); + cost.AddCost(Command::Do(flags, 0, old_v->index, 0, {})); /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, new_v->index, 0); + Command::Do(DC_EXEC, 0, new_v->index, 0, {}); } } @@ -598,7 +602,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON); /* Sell wagon */ - [[maybe_unused]] CommandCost ret = DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, wagon->index, 0); + [[maybe_unused]] CommandCost ret = Command::Do(DC_EXEC, 0, wagon->index, 0, {}); assert(ret.Succeeded()); new_vehs[i] = nullptr; @@ -630,7 +634,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Sell the vehicle. * Note: This might temporarily construct new trains, so use DC_AUTOREPLACE to prevent * it from failing due to engine limits. */ - cost.AddCost(DoCommand(flags | DC_AUTOREPLACE, CMD_SELL_VEHICLE, 0, w->index, 0)); + cost.AddCost(Command::Do(flags | DC_AUTOREPLACE, 0, w->index, 0, {})); if ((flags & DC_EXEC) != 0) { old_vehs[i] = nullptr; if (i == 0) old_head = nullptr; @@ -661,7 +665,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon if ((flags & DC_EXEC) == 0) { for (int i = num_units - 1; i >= 0; i--) { if (new_vehs[i] != nullptr) { - DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, new_vehs[i]->index, 0); + Command::Do(DC_EXEC, 0, new_vehs[i]->index, 0, {}); new_vehs[i] = nullptr; } } @@ -692,12 +696,12 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon } /* Sell the old vehicle */ - cost.AddCost(DoCommand(flags, CMD_SELL_VEHICLE, 0, old_head->index, 0)); + cost.AddCost(Command::Do(flags, 0, old_head->index, 0, {})); } /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, new_head->index, 0); + Command::Do(DC_EXEC, 0, new_head->index, 0, {}); } } } diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 3524b357c3..abd1f3da54 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -23,6 +23,7 @@ #include "cmd_helper.h" #include "tunnelbridge_map.h" #include "road_gui.h" +#include "tunnelbridge_cmd.h" #include "widgets/bridge_widget.h" @@ -391,7 +392,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo /* only query bridge building possibility once, result is the same for all bridges! * returns CMD_ERROR on failure, and price on success */ StringID errmsg = INVALID_STRING_ID; - CommandCost ret = DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)) | DC_QUERY_COST, CMD_BUILD_BRIDGE, end, start, type); + CommandCost ret = Command::Do(CommandFlagsToDCFlags(GetCommandFlags()) | DC_QUERY_COST, end, start, type, {}); GUIBridgeList *bl = nullptr; if (ret.Failed()) { diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 7901b45740..9082de5a97 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1228,7 +1228,7 @@ struct BuildVehicleWindow : Window { if (!this->listview_mode) { /* Query for cost and refitted capacity */ - CommandCost ret = DoCommand(DC_QUERY_COST, CMD_BUILD_VEHICLE, this->window_number, this->sel_engine | (cargo << 24), 0); + CommandCost ret = Command::Do(DC_QUERY_COST, this->window_number, this->sel_engine | (cargo << 24), 0, {}); if (ret.Succeeded()) { this->te.cost = ret.GetCost() - e->GetCost(); this->te.capacity = _returned_refit_capacity; diff --git a/src/clear_cmd.cpp b/src/clear_cmd.cpp index 918f5c373c..f2f7ecc197 100644 --- a/src/clear_cmd.cpp +++ b/src/clear_cmd.cpp @@ -16,6 +16,7 @@ #include "water.h" #include "core/random_func.hpp" #include "newgrf_generic.h" +#include "landscape_cmd.h" #include "table/strings.h" #include "table/sprites.h" @@ -381,7 +382,7 @@ static void ChangeTileOwner_Clear(TileIndex tile, Owner old_owner, Owner new_own static CommandCost TerraformTile_Clear(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(flags, tile, 0, 0, {}); } extern const TileTypeProcs _tile_type_clear_procs = { diff --git a/src/command.cpp b/src/command.cpp index 06025a949d..69cbaa6c92 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -164,64 +164,6 @@ bool IsCommandAllowedWhilePaused(Commands cmd) return _game_mode == GM_EDITOR || command_type_lookup[_command_proc_table[cmd].type] <= _settings_game.construction.command_pause_level; } - -/*! - * This function executes a given command with the parameters from the #CommandProc parameter list. - * Depending on the flags parameter it execute or test a command. - * - * @param flags Flags for the command and how to execute the command - * @param cmd The command-id to execute (a value of the CMD_* enums) - * @param tile The tile to apply the command on (for the #CommandProc) - * @param p1 Additional data for the command (for the #CommandProc) - * @param p2 Additional data for the command (for the #CommandProc) - * @param text The text to pass - * @see CommandProc - * @return the cost - */ -CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - CommandCost res; - - /* Do not even think about executing out-of-bounds tile-commands */ - if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return CMD_ERROR; - - /* Chop of any CMD_MSG or other flags; we don't need those here */ - CommandProc *proc = _command_proc_table[cmd].proc; - - RecursiveCommandCounter counter{}; - - /* only execute the test call if it's toplevel, or we're not execing. */ - if (counter.IsTopLevel() || !(flags & DC_EXEC) ) { - if (counter.IsTopLevel()) _cleared_object_areas.clear(); - SetTownRatingTestMode(true); - res = proc(flags & ~DC_EXEC, tile, p1, p2, text); - SetTownRatingTestMode(false); - if (res.Failed()) return res; - - if (counter.IsTopLevel() && - !(flags & DC_QUERY_COST) && - !(flags & DC_BANKRUPT) && - !CheckCompanyHasMoney(res)) { // CheckCompanyHasMoney() modifies 'res' to an error if it fails. - return res; - } - - if (!(flags & DC_EXEC)) return res; - } - - /* Execute the command here. All cost-relevant functions set the expenses type - * themselves to the cost object at some point */ - if (counter.IsTopLevel()) _cleared_object_areas.clear(); - res = proc(flags, tile, p1, p2, text); - if (res.Failed()) return res; - - /* if toplevel, subtract the money. */ - if (counter.IsTopLevel() && !(flags & DC_BANKRUPT)) { - SubtractMoneyFromCompany(res); - } - - return res; -} - /*! * This functions returns the money which can be used to execute a command. * This is either the money of the current company or INT64_MAX if there @@ -237,6 +179,40 @@ Money GetAvailableMoneyForCommand() } +/** + * Prepare for calling a command proc. + * @param top_level Top level of command execution, i.e. command from a command. + * @param test Test run of command? + */ +void CommandHelperBase::InternalDoBefore(bool top_level, bool test) +{ + if (top_level) _cleared_object_areas.clear(); + if (test) SetTownRatingTestMode(true); +} + +/** + * Process result after calling a command proc. + * @param[in,out] res Command result, may be modified. + * @param flags Command flags. + * @param top_level Top level of command execution, i.e. command from a command. + * @param test Test run of command? + */ +void CommandHelperBase::InternalDoAfter(CommandCost &res, DoCommandFlag flags, bool top_level, bool test) +{ + if (test) { + SetTownRatingTestMode(false); + + if (res.Succeeded() && top_level && !(flags & DC_QUERY_COST) && !(flags & DC_BANKRUPT)) { + CheckCompanyHasMoney(res); // CheckCompanyHasMoney() modifies 'res' to an error if it fails. + } + } else { + /* If top-level, subtract the money. */ + if (res.Succeeded() && top_level && !(flags & DC_BANKRUPT)) { + SubtractMoneyFromCompany(res); + } + } +} + /*! * Toplevel network safe docommand function for the current company. Must not be called recursively. * The callback is called when the command succeeded or failed. The parameters diff --git a/src/command_func.h b/src/command_func.h index 2a6f0c68a7..1c24221cd2 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -13,6 +13,7 @@ #include "command_type.h" #include "company_type.h" #include +#include "tile_map.h" /** * Define a default return value for a failed command. @@ -36,7 +37,6 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); /** Storage buffer for serialized command data. */ typedef std::vector CommandDataBuffer; -CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); bool DoCommandP(Commands cmd, StringID err_message, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); @@ -58,12 +58,18 @@ const char *GetCommandName(Commands cmd); Money GetAvailableMoneyForCommand(); bool IsCommandAllowedWhilePaused(Commands cmd); +template +constexpr CommandFlags GetCommandFlags() +{ + return CommandTraits::flags; +} + /** * Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags * @param cmd_flags Flags from GetCommandFlags * @return flags for DoCommand */ -static inline DoCommandFlag CommandFlagsToDCFlags(CommandFlags cmd_flags) +static constexpr inline DoCommandFlag CommandFlagsToDCFlags(CommandFlags cmd_flags) { DoCommandFlag flags = DC_NONE; if (cmd_flags & CMD_NO_WATER) flags |= DC_NO_WATER; @@ -83,4 +89,67 @@ private: static int _counter; }; + +template struct CommandHelper; + +class CommandHelperBase { +protected: + static void InternalDoBefore(bool top_level, bool test); + static void InternalDoAfter(CommandCost &res, DoCommandFlag flags, bool top_level, bool test); +}; + +/** + * Templated wrapper that exposes the command parameter arguments + * for the various Command::Do/Post calls. + * @tparam Tcmd The command-id to execute. + * @tparam Targs The command parameter types. + */ +template +struct CommandHelper : protected CommandHelperBase { +public: + /** + * This function executes a given command with the parameters from the #CommandProc parameter list. + * Depending on the flags parameter it executes or tests a command. + * + * @note This function is to be called from the StateGameLoop or from within the execution of a Command. + * This function must not be called from the context of a "player" (real person, AI, game script). + * Use ::Post for commands directly triggered by "players". + * + * @param flags Flags for the command and how to execute the command + * @param args Parameters for the command + * @see CommandProc + * @return the cost + */ + static CommandCost Do(DoCommandFlag flags, Targs... args) + { + if constexpr (std::is_same_v>>) { + /* Do not even think about executing out-of-bounds tile-commands. */ + TileIndex tile = std::get<0>(std::make_tuple(args...)); + if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return CMD_ERROR; + } + + RecursiveCommandCounter counter{}; + + /* Only execute the test call if it's toplevel, or we're not execing. */ + if (counter.IsTopLevel() || !(flags & DC_EXEC)) { + InternalDoBefore(counter.IsTopLevel(), true); + CommandCost res = CommandTraits::proc(flags & ~DC_EXEC, args...); + InternalDoAfter(res, flags, counter.IsTopLevel(), true); // Can modify res. + + if (res.Failed() || !(flags & DC_EXEC)) return res; + } + + /* Execute the command here. All cost-relevant functions set the expenses type + * themselves to the cost object at some point. */ + InternalDoBefore(counter.IsTopLevel(), false); + CommandCost res = CommandTraits::proc(flags, args...); + InternalDoAfter(res, flags, counter.IsTopLevel(), false); + + return res; + } +}; + +template +using Command = CommandHelper::ProcType>; + #endif /* COMMAND_FUNC_H */ diff --git a/src/command_type.h b/src/command_type.h index cc5e97795e..c182ca393e 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -435,7 +435,8 @@ template struct CommandTraits; #define DEF_CMD_TRAIT(cmd_, proc_, flags_, type_) \ template<> struct CommandTraits { \ - using Args = typename CommandFunctionTraitHelper::Args; \ + using ProcType = decltype(&proc_); \ + using Args = typename CommandFunctionTraitHelper::Args; \ static constexpr Commands cmd = cmd_; \ static constexpr auto &proc = proc_; \ static constexpr CommandFlags flags = (CommandFlags)(flags_); \ diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index f659a43673..6bd60659b7 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -1128,7 +1128,7 @@ CommandCost CmdRenamePresident(DoCommandFlag flags, TileIndex tile, uint32 p1, u c->president_name = text; if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) { - DoCommand(DC_EXEC, CMD_RENAME_COMPANY, 0, 0, 0, text + " Transport"); + Command::Do(DC_EXEC, 0, 0, 0, text + " Transport"); } } diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index 63f4188a88..6319af0ab2 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -45,6 +45,7 @@ #include "company_base.h" #include "core/random_func.hpp" #include "core/backup_type.hpp" +#include "landscape_cmd.h" #include "table/strings.h" @@ -61,7 +62,7 @@ static void DisasterClearSquare(TileIndex tile) case MP_RAILWAY: if (Company::IsHumanID(GetTileOwner(tile)) && !IsRailDepot(tile)) { Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); - DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + Command::Do(DC_EXEC, tile, 0, 0, {}); cur_company.Restore(); /* update signals in buffer */ @@ -71,7 +72,7 @@ static void DisasterClearSquare(TileIndex tile) case MP_HOUSE: { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); - DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + Command::Do(DC_EXEC, tile, 0, 0, {}); cur_company.Restore(); break; } diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index da7e0518f4..571bfdcec0 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -215,7 +215,7 @@ struct BuildDocksToolbarWindow : Window { auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_DOCK)), CMD_BUILD_DOCK, tile, p1, p2).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, p1, p2, {}).Succeeded(); } else { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); diff --git a/src/economy.cpp b/src/economy.cpp index 39e98342f9..e7daf8e3d1 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -49,6 +49,7 @@ #include "story_base.h" #include "linkgraph/refresh.h" #include "economy_cmd.h" +#include "vehicle_cmd.h" #include "table/strings.h" #include "table/pricebase.h" @@ -313,7 +314,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) for (i = 0; i < 4; i++) { if (c->share_owners[i] == old_owner) { /* Sell its shares */ - CommandCost res = DoCommand(DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY, 0, c->index, 0); + CommandCost res = Command::Do(DC_EXEC | DC_BANKRUPT, 0, c->index, 0, {}); /* Because we are in a DoCommand, we can't just execute another one and * expect the money to be removed. We need to do it ourself! */ SubtractMoneyFromCompany(res); @@ -333,7 +334,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } else { cur_company2.Change(c->share_owners[i]); /* Sell the shares */ - CommandCost res = DoCommand(DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY, 0, old_owner, 0); + CommandCost res = Command::Do(DC_EXEC | DC_BANKRUPT, 0, old_owner, 0, {}); /* Because we are in a DoCommand, we can't just execute another one and * expect the money to be removed. We need to do it ourself! */ SubtractMoneyFromCompany(res); @@ -449,7 +450,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) * However, do not rely on that behaviour. */ int interval = CompanyServiceInterval(new_company, v->type); - DoCommand(DC_EXEC | DC_BANKRUPT, CMD_CHANGE_SERVICE_INT, v->tile, v->index, interval | (new_company->settings.vehicle.servint_ispercent << 17)); + Command::Do(DC_EXEC | DC_BANKRUPT, v->tile, v->index, interval | (new_company->settings.vehicle.servint_ispercent << 17), {}); } v->owner = new_owner; @@ -1486,7 +1487,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station if (st->goods[cid].cargo.HasCargoFor(next_station)) { /* Try to find out if auto-refitting would succeed. In case the refit is allowed, * the returned refit capacity will be greater than zero. */ - DoCommand(DC_QUERY_COST, CMD_REFIT_VEHICLE, v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16); // Auto-refit and only this vehicle including artic parts. + Command::Do(DC_QUERY_COST, v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16, {}); // Auto-refit and only this vehicle including artic parts. /* Try to balance different loadable cargoes between parts of the consist, so that * all of them can be loaded. Avoid a situation where all vehicles suddenly switch * to the first loadable cargo for which there is only one packet. If the capacities @@ -1509,7 +1510,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station * "via any station" before reserving. We rather produce some more "any station" cargo than * misrouting it. */ IterateVehicleParts(v_start, ReturnCargoAction(st, INVALID_STATION)); - CommandCost cost = DoCommand(DC_EXEC, CMD_REFIT_VEHICLE, v_start->tile, v_start->index, new_cid | 1U << 24 | 0xFF << 8 | 1U << 16); // Auto-refit and only this vehicle including artic parts. + CommandCost cost = Command::Do(DC_EXEC, v_start->tile, v_start->index, new_cid | 1U << 24 | 0xFF << 8 | 1U << 16, {}); // Auto-refit and only this vehicle including artic parts. if (cost.Succeeded()) v->First()->profit_this_year -= cost.GetCost() << 8; } diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index fbe08ffd0c..2ff8a09dfd 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -357,12 +357,12 @@ CommandCost CmdDeleteGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 if (g == nullptr || g->owner != _current_company) return CMD_ERROR; /* Remove all vehicles from the group */ - DoCommand(flags, CMD_REMOVE_ALL_VEHICLES_GROUP, 0, p1, 0); + Command::Do(flags, 0, p1, 0, {}); /* Delete sub-groups */ for (const Group *gp : Group::Iterate()) { if (gp->parent == g->index) { - DoCommand(flags, CMD_DELETE_GROUP, 0, gp->index, 0); + Command::Do(flags, 0, gp->index, 0, {}); } } @@ -581,7 +581,7 @@ CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 /* For each shared vehicles add it to the group */ for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { - if (v2->group_id != id_g) DoCommand(flags, CMD_ADD_VEHICLE_GROUP, tile, id_g, v2->index, text); + if (v2->group_id != id_g) Command::Do(flags, tile, id_g, v2->index, text); } } } @@ -617,7 +617,7 @@ CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, TileIndex tile, uint3 if (v->group_id != old_g) continue; /* Add The Vehicle to the default group */ - DoCommand(flags, CMD_ADD_VEHICLE_GROUP, tile, DEFAULT_GROUP, v->index, text); + Command::Do(flags,tile, DEFAULT_GROUP, v->index, text); } } diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index e2fa1b7769..b7d6d3714c 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -43,6 +43,8 @@ #include "cmd_helper.h" #include "string_func.h" #include "industry_cmd.h" +#include "landscape_cmd.h" +#include "terraform_cmd.h" #include "table/strings.h" #include "table/industry_land.h" @@ -1101,7 +1103,7 @@ static bool SearchLumberMillTrees(TileIndex tile, void *user_data) _industry_sound_tile = tile; if (_settings_client.sound.ambient) SndPlayTileFx(SND_38_LUMBER_MILL_1, tile); - DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + Command::Do(DC_EXEC, tile, 0, 0, {}); cur_company.Restore(); return true; @@ -1483,13 +1485,13 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */ Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); - CommandCost ret = DoCommand(DC_NONE, CMD_LANDSCAPE_CLEAR, cur_tile, 0, 0); + CommandCost ret = Command::Do(DC_NONE, cur_tile, 0, 0, {}); cur_company.Restore(); if (ret.Failed()) return ret; } else { /* Clear the tiles, but do not affect town ratings */ - CommandCost ret = DoCommand(DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR, cur_tile, 0, 0); + CommandCost ret = Command::Do(DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, cur_tile, 0, 0, {}); if (ret.Failed()) return ret; } @@ -1599,7 +1601,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, } /* This is not 100% correct check, but the best we can do without modifying the map. * What is missing, is if the difference in height is more than 1.. */ - if (DoCommand(flags & ~DC_EXEC, CMD_TERRAFORM_LAND, tile_walk, SLOPE_N, (curh > h) ? 0 : 1).Failed()) { + if (Command::Do(flags & ~DC_EXEC, tile_walk, SLOPE_N, (curh > h) ? 0 : 1, {}).Failed()) { cur_company.Restore(); return false; } @@ -1614,7 +1616,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, /* We give the terraforming for free here, because we can't calculate * exact cost in the test-round, and as we all know, that will cause * a nice assert if they don't match ;) */ - DoCommand(flags, CMD_TERRAFORM_LAND, tile_walk, SLOPE_N, (curh > h) ? 0 : 1); + Command::Do(flags, tile_walk, SLOPE_N, (curh > h) ? 0 : 1, {}); curh += (curh > h) ? -1 : 1; } } @@ -1884,7 +1886,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID); - DoCommand(DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR, cur_tile, 0, 0); + Command::Do(DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, cur_tile, 0, 0, {}); MakeIndustry(cur_tile, i->index, it.gfx, Random(), wc); @@ -3060,7 +3062,7 @@ static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, i } } } - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(flags, tile, 0, 0, {}); } extern const TileTypeProcs _tile_type_industry_procs = { diff --git a/src/landscape.cpp b/src/landscape.cpp index 1259617ace..6efa8dba29 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -756,7 +756,7 @@ CommandCost CmdClearArea(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 TileIterator *iter = HasBit(p2, 0) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex t = *iter; - CommandCost ret = DoCommand(flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR, t, 0, 0); + CommandCost ret = Command::Do(flags & ~DC_EXEC, t, 0, 0, {}); if (ret.Failed()) { last_error = ret; @@ -773,7 +773,7 @@ CommandCost CmdClearArea(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 delete iter; return cost; } - DoCommand(flags, CMD_LANDSCAPE_CLEAR, t, 0, 0); + Command::Do(flags, t, 0, 0, {}); /* draw explosion animation... * Disable explosions when game is paused. Looks silly and blocks the view. */ diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 859798deb1..b2e8b886e0 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -26,6 +26,7 @@ #include "zoom_func.h" #include "guitimer_func.h" #include "viewport_func.h" +#include "landscape_cmd.h" #include "rev.h" #include "widgets/misc_widget.h" @@ -191,7 +192,7 @@ public: Company *c = Company::GetIfValid(_local_company); if (c != nullptr) { assert(_current_company == _local_company); - CommandCost costclear = DoCommand(DC_QUERY_COST, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + CommandCost costclear = Command::Do(DC_QUERY_COST, tile, 0, 0, {}); if (costclear.Succeeded()) { Money cost = costclear.GetCost(); if (cost < 0) { diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index b5271727ce..a651239baf 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -34,6 +34,7 @@ #include "vehicle_func.h" #include "station_func.h" #include "object_cmd.h" +#include "landscape_cmd.h" #include "table/strings.h" #include "table/object_land.h" @@ -230,7 +231,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 if (type == OBJECT_OWNED_LAND) { /* Owned land is special as it can be placed on any slope. */ - cost.AddCost(DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0)); + cost.AddCost(Command::Do(flags, tile, 0, 0, {})); } else { /* Check the surface to build on. At this time we can't actually execute the * the CLEAR_TILE commands since the newgrf callback later on can check @@ -243,7 +244,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 if (!IsWaterTile(t)) { /* Normal water tiles don't have to be cleared. For all other tile types clear * the tile but leave the water. */ - cost.AddCost(DoCommand(flags & ~DC_NO_WATER & ~DC_EXEC, CMD_LANDSCAPE_CLEAR, t, 0, 0)); + cost.AddCost(Command::Do(flags & ~DC_NO_WATER & ~DC_EXEC, t, 0, 0, {})); } else { /* Can't build on water owned by another company. */ Owner o = GetTileOwner(t); @@ -261,7 +262,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 IsTileType(t, MP_OBJECT) && IsTileOwner(t, _current_company) && IsObjectType(t, OBJECT_HQ))) { - cost.AddCost(DoCommand(flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR, t, 0, 0)); + cost.AddCost(Command::Do(flags & ~DC_EXEC, t, 0, 0, {})); } } } @@ -293,10 +294,10 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 for (TileIndex t : ta) { if (HasTileWaterGround(t)) { if (!IsWaterTile(t)) { - DoCommand((flags & ~DC_NO_WATER) | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR, t, 0, 0); + Command::Do((flags & ~DC_NO_WATER) | DC_NO_MODIFY_TOWN_RATING, t, 0, 0, {}); } } else { - DoCommand(flags | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR, t, 0, 0); + Command::Do(flags | DC_NO_MODIFY_TOWN_RATING, t, 0, 0, {}); } } } @@ -848,7 +849,7 @@ static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlag flags, int } } - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(flags, tile, 0, 0, {}); } extern const TileTypeProcs _tile_type_object_procs = { diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 76c416abd3..80fc9fa6d1 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -17,6 +17,7 @@ #include "window_func.h" #include "station_map.h" #include "order_cmd.h" +#include "group_cmd.h" #include "safeguards.h" @@ -74,7 +75,7 @@ void OrderBackup::DoRestore(Vehicle *v) { /* If we had shared orders, recover that */ if (this->clone != nullptr) { - DoCommand(DC_EXEC, CMD_CLONE_ORDER, 0, v->index | CO_SHARE << 30, this->clone->index); + Command::Do(DC_EXEC, 0, v->index | CO_SHARE << 30, this->clone->index, {}); } else if (this->orders != nullptr && OrderList::CanAllocateItem()) { v->orders.list = new OrderList(this->orders, v); this->orders = nullptr; @@ -89,7 +90,7 @@ void OrderBackup::DoRestore(Vehicle *v) if (v->cur_implicit_order_index >= v->GetNumOrders()) v->cur_implicit_order_index = v->cur_real_order_index; /* Restore vehicle group */ - DoCommand(DC_EXEC, CMD_ADD_VEHICLE_GROUP, 0, this->group, v->index); + Command::Do(DC_EXEC, 0, this->group, v->index, {}); } /** diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index e48cc95c17..45a0db99fe 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -27,6 +27,7 @@ #include "order_backup.h" #include "cheat_type.h" #include "order_cmd.h" +#include "train_cmd.h" #include "table/strings.h" @@ -2037,7 +2038,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool v->current_order.MakeGoToDepot(destination, v->current_order.GetDepotOrderType(), v->current_order.GetNonStopType(), (OrderDepotActionFlags)(v->current_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT), v->current_order.GetRefitCargo()); /* If there is no depot in front, reverse automatically (trains only) */ - if (v->type == VEH_TRAIN && reverse) DoCommand(DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION, v->tile, v->index, 0); + if (v->type == VEH_TRAIN && reverse) Command::Do(DC_EXEC, v->tile, v->index, 0, {}); if (v->type == VEH_AIRCRAFT) { Aircraft *a = Aircraft::From(v); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index af99b03ae2..066fb78200 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -32,6 +32,7 @@ #include "company_gui.h" #include "object_map.h" #include "rail_cmd.h" +#include "landscape_cmd.h" #include "table/strings.h" #include "table/railtypes.h" @@ -452,7 +453,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, u CommandCost ret = CheckTileOwnership(tile); if (ret.Failed()) return ret; - if (!IsPlainRail(tile)) return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); // just get appropriate error message + if (!IsPlainRail(tile)) return Command::Do(flags, tile, 0, 0, {}); // just get appropriate error message if (!IsCompatibleRail(GetRailType(tile), railtype)) return_cmd_error(STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION); @@ -470,7 +471,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, u for (Track track_it = TRACK_BEGIN; track_it < TRACK_END; track_it++) { if (HasTrack(tile, track_it) && HasSignalOnTrack(tile, track_it)) { - CommandCost ret_remove_signals = DoCommand(flags, CMD_REMOVE_SIGNALS, tile, track_it, 0); + CommandCost ret_remove_signals = Command::Do(flags, tile, track_it, 0, {}); if (ret_remove_signals.Failed()) return ret_remove_signals; cost.AddCost(ret_remove_signals); } @@ -482,7 +483,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, u * the present rail type are powered on the new rail type. */ if (GetRailType(tile) != railtype && !HasPowerOnRail(railtype, GetRailType(tile))) { if (HasPowerOnRail(GetRailType(tile), railtype)) { - ret = DoCommand(flags, CMD_CONVERT_RAIL, tile, tile, railtype); + ret = Command::Do(flags, tile, tile, railtype, {}); if (ret.Failed()) return ret; cost.AddCost(ret); } else { @@ -582,7 +583,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, u if (ret.Failed()) return ret; cost.AddCost(ret); - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + ret = Command::Do(flags, tile, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -692,7 +693,7 @@ CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, /* Charge extra to remove signals on the track, if they are there */ if (HasSignalOnTrack(tile, track)) { - cost.AddCost(DoCommand(flags, CMD_REMOVE_SIGNALS, tile, track, 0)); + cost.AddCost(Command::Do(flags, tile, track, 0, {})); } if (flags & DC_EXEC) { @@ -785,7 +786,7 @@ bool FloodHalftile(TileIndex t) TrackBits to_remove = lower_track & rail_bits; if (to_remove != 0) { Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); - flooded = DoCommand(DC_EXEC, CMD_REMOVE_SINGLE_RAIL, t, 0, FIND_FIRST_BIT(to_remove)).Succeeded(); + flooded = Command::Do(DC_EXEC, t, 0, FIND_FIRST_BIT(to_remove), {}).Succeeded(); cur_company.Restore(); if (!flooded) return flooded; // not yet floodable rail_bits = rail_bits & ~to_remove; @@ -904,7 +905,8 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, uint3 bool had_success = false; CommandCost last_error = CMD_ERROR; for (;;) { - CommandCost ret = DoCommand(flags, remove ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL, tile, remove ? 0 : railtype, TrackdirToTrack(trackdir) | (auto_remove_signals << 3)); + uint32 p2 = TrackdirToTrack(trackdir) | (auto_remove_signals << 3); + CommandCost ret = remove ? Command::Do(flags, tile, 0, p2, {}) : Command::Do(flags, tile, railtype, p2, {}); if (ret.Failed()) { last_error = ret; @@ -1008,7 +1010,7 @@ CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, u cost.AddCost(_price[PR_BUILD_FOUNDATION]); } - cost.AddCost(DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0)); + cost.AddCost(Command::Do(flags, tile, 0, 0, {})); if (cost.Failed()) return cost; if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -1359,7 +1361,8 @@ static CommandCost CmdSignalTrackHelper(DoCommandFlag flags, TileIndex tile, uin if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(trackdir); if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(trackdir); - CommandCost ret = DoCommand(test_only ? flags & ~DC_EXEC : flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS, tile, param1, signals); + DoCommandFlag do_flags = test_only ? flags & ~DC_EXEC : flags; + CommandCost ret = remove ? Command::Do(do_flags, tile, param1, signals, {}) : Command::Do(do_flags, tile, param1, signals, {}); if (test_only) return ret.Succeeded(); @@ -1879,7 +1882,7 @@ static CommandCost ClearTile_Track(TileIndex tile, DoCommandFlag flags) TrackBits tracks = GetTrackBits(tile); while (tracks != TRACK_BIT_NONE) { Track track = RemoveFirstTrack(&tracks); - CommandCost ret = DoCommand(flags, CMD_REMOVE_SINGLE_RAIL, tile, 0, track); + CommandCost ret = Command::Do(flags, tile, 0, track, {}); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -2953,7 +2956,7 @@ static void ChangeTileOwner_Track(TileIndex tile, Owner old_owner, Owner new_own SetTileOwner(tile, new_owner); } else { - DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); } } @@ -3141,7 +3144,7 @@ static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, int AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) { return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(flags, tile, 0, 0, {}); } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 76d51ccb2c..f88352f9e6 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -37,6 +37,7 @@ #include "stringfilter_type.h" #include "string_func.h" #include "station_cmd.h" +#include "tunnelbridge_cmd.h" #include "waypoint_cmd.h" #include "station_map.h" @@ -202,7 +203,7 @@ static void PlaceRail_Station(TileIndex tile) auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_RAIL_STATION)), CMD_BUILD_RAIL_STATION, tile, p1, p2).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, p1, p2, {}).Succeeded(); } else { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); @@ -738,7 +739,7 @@ struct BuildRailToolbarWindow : Window { auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_RAIL_WAYPOINT)), CMD_BUILD_RAIL_WAYPOINT, ta.tile, p1, p2).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, p1, p2, {}).Succeeded(); } else { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); @@ -773,7 +774,7 @@ struct BuildRailToolbarWindow : Window { void OnPlacePresize(Point pt, TileIndex tile) override { - DoCommand(DC_AUTO, CMD_BUILD_TUNNEL, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0); + Command::Do(DC_AUTO, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, {}); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); } @@ -907,7 +908,7 @@ static void HandleStationPlacement(TileIndex start, TileIndex end) auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_RAIL_STATION)), CMD_BUILD_RAIL_STATION, ta.tile, p1, p2).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, p1, p2, {}).Succeeded(); } else { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 6fa8244e1e..637b476d0d 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -38,6 +38,8 @@ #include "company_gui.h" #include "road_func.h" #include "road_cmd.h" +#include "landscape_cmd.h" +#include "rail_cmd.h" #include "table/strings.h" #include "table/roadtypes.h" @@ -367,7 +369,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec if (!IsTileType(tile, MP_ROAD)) { /* If it's the last roadtype, just clear the whole tile */ - if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) return Command::Do(flags, tile, 0, 0, {}); CommandCost cost(EXPENSES_CONSTRUCTION); if (IsTileType(tile, MP_TUNNELBRIDGE)) { @@ -822,7 +824,7 @@ do_clear:; } if (need_to_clear) { - CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + CommandCost ret = Command::Do(flags, tile, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -868,7 +870,7 @@ do_clear:; if (HasPowerOnRoad(rt, existing_rt)) { rt = existing_rt; } else if (HasPowerOnRoad(existing_rt, rt)) { - CommandCost ret = DoCommand(flags, CMD_CONVERT_ROAD, tile, tile, rt); + CommandCost ret = Command::Do(flags, tile, tile, rt, {}); if (ret.Failed()) return ret; cost.AddCost(ret); } else { @@ -1039,7 +1041,7 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p if (tile == start_tile && HasBit(p2, 0)) bits &= DiagDirToRoadBits(dir); } - CommandCost ret = DoCommand(flags, CMD_BUILD_ROAD, tile, drd << 11 | rt << 4 | bits, 0); + CommandCost ret = Command::Do(flags, tile, drd << 11 | rt << 4 | bits, 0, {}); if (ret.Failed()) { last_error = ret; if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) { @@ -1130,7 +1132,7 @@ CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 if (flags & DC_EXEC) { money_spent += ret.GetCost(); if (money_spent > 0 && money_spent > money_available) { - _additional_cash_required = DoCommand(flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD, start_tile, end_tile, p2).GetCost(); + _additional_cash_required = Command::Do(flags & ~DC_EXEC, start_tile, end_tile, p2, {}).GetCost(); return cost; } RemoveRoad(tile, flags, bits, rtt, true, false); @@ -1181,7 +1183,7 @@ CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, ui cost.AddCost(_price[PR_BUILD_FOUNDATION]); } - cost.AddCost(DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0)); + cost.AddCost(Command::Do(flags, tile, 0, 0, {})); if (cost.Failed()) return cost; if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -1267,7 +1269,7 @@ static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags) } if (flags & DC_EXEC) { - DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + Command::Do(flags, tile, 0, 0, {}); } return ret; } @@ -2195,7 +2197,7 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne if (IsRoadDepot(tile)) { if (GetTileOwner(tile) == old_owner) { if (new_owner == INVALID_OWNER) { - DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); } else { /* A road depot has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */ RoadType rt = GetRoadTypeRoad(tile); @@ -2232,7 +2234,7 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne if (IsLevelCrossing(tile)) { if (GetTileOwner(tile) == old_owner) { if (new_owner == INVALID_OWNER) { - DoCommand(DC_EXEC | DC_BANKRUPT, CMD_REMOVE_SINGLE_RAIL, tile, 0, GetCrossingRailTrack(tile)); + Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, GetCrossingRailTrack(tile), {}); } else { /* Update infrastructure counts. No need to dirty windows here, we'll redraw the whole screen anyway. */ Company::Get(old_owner)->infrastructure.rail[GetRailType(tile)] -= LEVELCROSSING_TRACKBIT_FACTOR; @@ -2281,7 +2283,7 @@ static CommandCost TerraformTile_Road(TileIndex tile, DoCommandFlag flags, int z } } - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(flags, tile, 0, 0, {}); } /** Update power of road vehicle under which is the roadtype being converted */ diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 00ea29042d..145934ffc5 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -32,6 +32,7 @@ #include "core/geometry_func.hpp" #include "date_func.h" #include "station_cmd.h" +#include "tunnelbridge_cmd.h" #include "widgets/road_widget.h" @@ -199,7 +200,7 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, S auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_ROAD_STOP)), CMD_BUILD_ROAD_STOP, ta.tile, p1, p2).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, p1, p2, {}).Succeeded(); } else { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); @@ -722,7 +723,7 @@ struct BuildRoadToolbarWindow : Window { void OnPlacePresize(Point pt, TileIndex tile) override { - DoCommand(DC_AUTO, CMD_BUILD_TUNNEL, tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0); + Command::Do(DC_AUTO, tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, {}); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); } diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 4c83814033..efe45c507d 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -35,6 +35,7 @@ #include "zoom_func.h" #include "framerate_type.h" #include "roadveh_cmd.h" +#include "road_cmd.h" #include "table/strings.h" @@ -1134,7 +1135,7 @@ static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadType rt, RoadB /* The 'current' company is not necessarily the owner of the vehicle. */ Backup cur_company(_current_company, c, FILE_LINE); - CommandCost ret = DoCommand(DC_NO_WATER, CMD_BUILD_ROAD, t, rt << 4 | r, 0); + CommandCost ret = Command::Do(DC_NO_WATER, t, rt << 4 | r, 0, {}); cur_company.Restore(); return ret.Succeeded(); diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index 720e922f12..56fdde8261 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -9,13 +9,13 @@ #include "../../stdafx.h" #include "../../script/squirrel.hpp" -#include "../../command_func.h" #include "../../company_func.h" #include "../../company_base.h" #include "../../network/network.h" #include "../../genworld.h" #include "../../string_func.h" #include "../../strings_func.h" +#include "../../command_func.h" #include "../script_storage.hpp" #include "../script_instance.hpp" diff --git a/src/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp index 9e2a56e923..a062616185 100644 --- a/src/script/api/script_vehicle.cpp +++ b/src/script/api/script_vehicle.cpp @@ -20,6 +20,7 @@ #include "../../train.h" #include "../../vehicle_func.h" #include "../../aircraft.h" +#include "../../vehicle_cmd.h" #include "table/strings.h" #include "../../safeguards.h" @@ -91,7 +92,7 @@ if (!ScriptEngine::IsBuildable(engine_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; - CommandCost res = ::DoCommand(DC_QUERY_COST, CMD_BUILD_VEHICLE, depot, engine_id | (cargo << 24), 0); + CommandCost res = ::Command::Do(DC_QUERY_COST, depot, engine_id | (cargo << 24), 0, {}); return res.Succeeded() ? _returned_refit_capacity : -1; } @@ -140,7 +141,7 @@ if (!IsValidVehicle(vehicle_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; - CommandCost res = ::DoCommand(DC_QUERY_COST, CMD_REFIT_VEHICLE, 0, vehicle_id, cargo); + CommandCost res = ::Command::Do(DC_QUERY_COST, 0, vehicle_id, cargo, {}); return res.Succeeded() ? _returned_refit_capacity : -1; } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index f53523bc31..33f86146c4 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -58,6 +58,8 @@ #include "tunnelbridge_map.h" #include "station_cmd.h" #include "waypoint_cmd.h" +#include "landscape_cmd.h" +#include "rail_cmd.h" #include "table/strings.h" @@ -843,7 +845,7 @@ static CommandCost CheckFlatLandAirport(AirportTileTableIterator tile_iter, DoCo if (ret.Failed()) return ret; cost.AddCost(ret); - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_iter, 0, 0); + ret = Command::Do(flags, tile_iter, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -923,14 +925,14 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl affected_vehicles.push_back(v); } } - CommandCost ret = DoCommand(flags, CMD_REMOVE_SINGLE_RAIL, tile_cur, 0, track); + CommandCost ret = Command::Do(flags, tile_cur, 0, track, {}); if (ret.Failed()) return ret; cost.AddCost(ret); /* With flags & ~DC_EXEC CmdLandscapeClear would fail since the rail still exists */ continue; } } - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_cur, 0, 0); + ret = Command::Do(flags, tile_cur, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -1048,7 +1050,7 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags cost.AddCost(RoadBuildCost(rt) * 2); } } else { - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, cur_tile, 0, 0); + ret = Command::Do(flags, cur_tile, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); cost.AddCost(RoadBuildCost(rt) * 2); @@ -1754,7 +1756,7 @@ static CommandCost RemoveRailStation(TileIndex tile, DoCommandFlag flags) { /* if there is flooding, remove platforms tile by tile */ if (_current_company == OWNER_WATER) { - return DoCommand(DC_EXEC, CMD_REMOVE_FROM_RAIL_STATION, tile, 0, 0); + return Command::Do(DC_EXEC, tile, 0, 0, {}); } Station *st = Station::GetByTile(tile); @@ -1775,7 +1777,7 @@ static CommandCost RemoveRailWaypoint(TileIndex tile, DoCommandFlag flags) { /* if there is flooding, remove waypoints tile by tile */ if (_current_company == OWNER_WATER) { - return DoCommand(DC_EXEC, CMD_REMOVE_FROM_RAIL_WAYPOINT, tile, 0, 0); + return Command::Do(DC_EXEC, tile, 0, 0, {}); } return RemoveRailStation(Waypoint::GetByTile(tile), flags, _price[PR_CLEAR_WAYPOINT_RAIL]); @@ -2537,7 +2539,7 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_STATION_DOCK]); - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + ret = Command::Do(flags, tile, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -2552,7 +2554,7 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Get the water class of the water tile before it is cleared.*/ WaterClass wc = GetWaterClass(tile_cur); - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_cur, 0, 0); + ret = Command::Do(flags, tile_cur, 0, 0, {}); if (ret.Failed()) return ret; tile_cur += TileOffsByDiagDir(direction); @@ -4242,12 +4244,12 @@ static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_o } else { if (IsDriveThroughStopTile(tile)) { /* Remove the drive-through road stop */ - DoCommand(DC_EXEC | DC_BANKRUPT, CMD_REMOVE_ROAD_STOP, tile, 1 | 1 << 8, (GetStationType(tile) == STATION_TRUCK) ? ROADSTOP_TRUCK : ROADSTOP_BUS); + Command::Do(DC_EXEC | DC_BANKRUPT, tile, 1 | 1 << 8, (GetStationType(tile) == STATION_TRUCK) ? ROADSTOP_TRUCK : ROADSTOP_BUS, {}); assert(IsTileType(tile, MP_ROAD)); /* Change owner of tile and all roadtypes */ ChangeTileOwner(tile, old_owner, new_owner); } else { - DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); /* Set tile owner of water under (now removed) buoy and dock to OWNER_NONE. * Update owner of buoy if it was not removed (was in orders). * Do not update when owned by OWNER_WATER (sea and rivers). */ @@ -4364,7 +4366,7 @@ static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, in } } } - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(flags, tile, 0, 0, {}); } /** diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index 17da36ecc8..df178e3abf 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -18,6 +18,7 @@ #include "company_func.h" #include "core/backup_type.hpp" #include "terraform_cmd.h" +#include "landscape_cmd.h" #include "table/strings.h" @@ -290,7 +291,7 @@ CommandCost CmdTerraformLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uin } CommandCost cost; if (indirectly_cleared) { - cost = DoCommand(tile_flags, CMD_LANDSCAPE_CLEAR, t, 0, 0); + cost = Command::Do(tile_flags, t, 0, 0, {}); } else { cost = _tile_type_procs[GetTileType(t)]->terraform_tile_proc(t, tile_flags, z_min, tileh); } @@ -379,7 +380,7 @@ CommandCost CmdLevelLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 TileIndex t = *iter; uint curh = TileHeight(t); while (curh != h) { - CommandCost ret = DoCommand(flags & ~DC_EXEC, CMD_TERRAFORM_LAND, t, SLOPE_N, (curh > h) ? 0 : 1); + CommandCost ret = Command::Do(flags & ~DC_EXEC, t, SLOPE_N, (curh > h) ? 0 : 1, {}); if (ret.Failed()) { last_error = ret; @@ -395,7 +396,7 @@ CommandCost CmdLevelLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 delete iter; return cost; } - DoCommand(flags, CMD_TERRAFORM_LAND, t, SLOPE_N, (curh > h) ? 0 : 1); + Command::Do(flags, t, SLOPE_N, (curh > h) ? 0 : 1, {}); } else { /* When we're at the terraform limit we better bail (unneeded) testing as well. * This will probably cause the terraforming cost to be underestimated, but only diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 498d057aa1..71d897c3d9 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -34,6 +34,7 @@ #include "terraform_cmd.h" #include "zoom_func.h" #include "rail_cmd.h" +#include "landscape_cmd.h" #include "widgets/terraform_widget.h" @@ -513,7 +514,7 @@ static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed) /* Delete all station signs */ for (BaseStation *st : BaseStation::Iterate()) { /* There can be buoys, remove them */ - if (IsBuoyTile(st->xy)) DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, st->xy, 0, 0); + if (IsBuoyTile(st->xy)) Command::Do(DC_EXEC | DC_BANKRUPT, st->xy, 0, 0, {}); if (!st->IsInUse()) delete st; } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 2f961b9cb0..8e87739d3d 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -49,6 +49,10 @@ #include "ai/ai.hpp" #include "game/game.hpp" #include "town_cmd.h" +#include "landscape_cmd.h" +#include "road_cmd.h" +#include "terraform_cmd.h" +#include "tunnelbridge_cmd.h" #include "table/strings.h" #include "table/town_land.h" @@ -939,8 +943,8 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) * If that fails clear the land, and if that fails exit. * This is to make sure that we can build a road here later. */ RoadType rt = GetTownRoadType(t); - if (DoCommand(DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD, tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X) | (rt << 4), 0).Failed() && - DoCommand(DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Failed()) { + if (Command::Do(DC_AUTO | DC_NO_WATER, tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X) | (rt << 4), 0, {}).Failed() && + Command::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Failed()) { return false; } } @@ -957,8 +961,8 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) CommandCost res = CMD_ERROR; if (!_generating_world && Chance16(1, 10)) { /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */ - res = DoCommand(DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND, - tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, 0); + res = Command::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, + tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, 0, {}); } if (res.Failed() && Chance16(1, 3)) { /* We can consider building on the slope, though. */ @@ -974,9 +978,9 @@ static bool TerraformTownTile(TileIndex tile, int edges, int dir) { assert(tile < MapSize()); - CommandCost r = DoCommand(DC_AUTO | DC_NO_WATER, CMD_TERRAFORM_LAND, tile, edges, dir); + CommandCost r = Command::Do(DC_AUTO | DC_NO_WATER, tile, edges, dir, {}); if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false; - DoCommand(DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_TERRAFORM_LAND, tile, edges, dir); + Command::Do(DC_AUTO | DC_NO_WATER | DC_EXEC, tile, edges, dir, {}); return true; } @@ -1108,7 +1112,7 @@ static bool GrowTownWithExtraHouse(Town *t, TileIndex tile) static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd) { RoadType rt = GetTownRoadType(t); - if (DoCommand(DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD, tile, rcmd | (rt << 4), t->index).Succeeded()) { + if (Command::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile, rcmd | (rt << 4), t->index, {}).Succeeded()) { _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1155,7 +1159,7 @@ static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, con if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false; /* If a road tile can be built, the construction is allowed. */ - return DoCommand(DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD, next_tile, rcmd | (rt << 4), t->index).Succeeded(); + return Command::Do(DC_AUTO | DC_NO_WATER, next_tile, rcmd | (rt << 4), t->index, {}).Succeeded(); } /** @@ -1223,8 +1227,8 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi /* Can we actually build the bridge? */ RoadType rt = GetTownRoadType(t); - if (DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE, tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15).Succeeded()) { - DoCommand(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE, tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15); + if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, {}).Succeeded()) { + Command::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags()), tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, {}); _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1294,8 +1298,8 @@ static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDi /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */ RoadType rt = GetTownRoadType(t); - if (DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL, tile, rt | (TRANSPORT_ROAD << 8), 0).Succeeded()) { - DoCommand(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_TUNNEL)), CMD_BUILD_TUNNEL, tile, rt | (TRANSPORT_ROAD << 8), 0); + if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, rt | (TRANSPORT_ROAD << 8), 0, {}).Succeeded()) { + Command::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags()), tile, rt | (TRANSPORT_ROAD << 8), 0, {}); _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1733,9 +1737,9 @@ static bool GrowTown(Town *t) for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { /* Only work with plain land that not already has a house */ if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) { - if (DoCommand(DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Succeeded()) { + if (Command::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Succeeded()) { RoadType rt = GetTownRoadType(t); - DoCommand(DC_EXEC | DC_AUTO, CMD_BUILD_ROAD, tile, GenRandomRoadBits() | (rt << 4), t->index); + Command::Do(DC_EXEC | DC_AUTO, tile, GenRandomRoadBits() | (rt << 4), t->index, {}); cur_company.Restore(); return true; } @@ -2180,7 +2184,7 @@ static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size if (t->cache.population > 0) return t; Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); - [[maybe_unused]] CommandCost rc = DoCommand(DC_EXEC, CMD_DELETE_TOWN, t->xy, t->index, 0); + [[maybe_unused]] CommandCost rc = Command::Do(DC_EXEC, t->xy, t->index, 0, {}); cur_company.Restore(); assert(rc.Succeeded()); @@ -2281,7 +2285,7 @@ HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile) */ static inline void ClearMakeHouseTile(TileIndex tile, Town *t, byte counter, byte stage, HouseID type, byte random_bits) { - [[maybe_unused]] CommandCost cc = DoCommand(DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + [[maybe_unused]] CommandCost cc = Command::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile, 0, 0, {}); assert(cc.Succeeded()); IncreaseBuildingCount(t, type); @@ -2338,7 +2342,7 @@ static inline bool CanBuildHouseHere(TileIndex tile, bool noslope) if (IsBridgeAbove(tile)) return false; /* can we clear the land? */ - return DoCommand(DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Succeeded(); + return Command::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Succeeded(); } @@ -2973,7 +2977,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Non-oil rig stations are always a problem. */ if (!(st->facilities & FACIL_AIRPORT) || st->airport.type != AT_OILRIG) return CMD_ERROR; /* We can only automatically delete oil rigs *if* there's no vehicle on them. */ - CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, st->airport.tile, 0, 0); + CommandCost ret = Command::Do(flags, st->airport.tile, 0, 0, {}); if (ret.Failed()) return ret; } } @@ -2989,7 +2993,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 * tile was already deleted earlier in the loop. */ for (TileIndex current_tile = 0; current_tile < MapSize(); ++current_tile) { if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) { - CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0); + CommandCost ret = Command::Do(flags, current_tile, 0, 0, {}); if (ret.Failed()) return ret; } } @@ -3032,7 +3036,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 break; } if (try_clear) { - CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0); + CommandCost ret = Command::Do(flags, current_tile, 0, 0, {}); if (ret.Failed()) return ret; } } @@ -3108,7 +3112,7 @@ static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags) static bool TryClearTile(TileIndex tile) { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); - CommandCost r = DoCommand(DC_NONE, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + CommandCost r = Command::Do(DC_NONE, tile, 0, 0, {}); cur_company.Restore(); return r.Succeeded(); } @@ -3180,7 +3184,7 @@ static CommandCost TownActionBuildStatue(Town *t, DoCommandFlag flags) if (flags & DC_EXEC) { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); - DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, statue_data.best_position, 0, 0); + Command::Do(DC_EXEC, statue_data.best_position, 0, 0, {}); cur_company.Restore(); BuildObject(OBJECT_STATUE, statue_data.best_position, _current_company, t); SetBit(t->statues, _current_company); // Once found and built, "inform" the Town. @@ -3787,7 +3791,7 @@ static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, int z } } - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(flags, tile, 0, 0, {}); } /** Tile callback functions for a town */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 5a36d0d868..b060ecdbad 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -655,7 +655,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const w->engine_type == e->index && ///< Same type w->First() != v && ///< Don't connect to ourself !(w->vehstatus & VS_CRASHED)) { ///< Not crashed/flooded - if (DoCommand(DC_EXEC, CMD_MOVE_RAIL_VEHICLE, 0, v->index | 1 << 20, w->Last()->index).Succeeded()) { + if (Command::Do(DC_EXEC, 0, v->index | 1 << 20, w->Last()->index, {}).Succeeded()) { break; } } @@ -671,7 +671,7 @@ static void NormalizeTrainVehInDepot(const Train *u) for (const Train *v : Train::Iterate()) { if (v->IsFreeWagon() && v->tile == u->tile && v->track == TRACK_BIT_DEPOT) { - if (DoCommand(DC_EXEC, CMD_MOVE_RAIL_VEHICLE, 0, v->index | 1 << 20, u->index).Failed()) { + if (Command::Do(DC_EXEC, 0, v->index | 1 << 20, u->index, {}).Failed()) { break; } } diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index ab439cd58e..79eaa04215 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -24,6 +24,7 @@ #include "newgrf_generic.h" #include "date_func.h" #include "tree_cmd.h" +#include "landscape_cmd.h" #include "table/strings.h" #include "table/tree_land.h" @@ -461,7 +462,7 @@ CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 switch (GetRawClearGround(current_tile)) { case CLEAR_FIELDS: case CLEAR_ROCKS: { - CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0); + CommandCost ret = Command::Do(flags, current_tile, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); break; @@ -882,7 +883,7 @@ void InitializeTrees() static CommandCost TerraformTile_Trees(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(flags, tile, 0, 0, {}); } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 07fcd4446a..85c611ae5d 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -41,6 +41,8 @@ #include "company_gui.h" #include "station_func.h" #include "tunnelbridge_cmd.h" +#include "landscape_cmd.h" +#include "terraform_cmd.h" #include "table/strings.h" #include "table/bridge_land.h" @@ -419,7 +421,7 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, u bool allow_on_slopes = (_settings_game.construction.build_on_slopes && transport_type != TRANSPORT_WATER); /* Try and clear the start landscape */ - CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_start, 0, 0); + CommandCost ret = Command::Do(flags, tile_start, 0, 0, {}); if (ret.Failed()) return ret; cost = ret; @@ -427,7 +429,7 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, u cost.AddCost(terraform_cost_north); /* Try and clear the end landscape */ - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile_end, 0, 0); + ret = Command::Do(flags, tile_end, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -499,7 +501,7 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, u default: not_valid_below:; /* try and clear the middle landscape */ - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + ret = Command::Do(flags, tile, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); break; @@ -673,7 +675,7 @@ CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, uint32 p1, if (HasTileWaterGround(start_tile)) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER); - CommandCost ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, start_tile, 0, 0); + CommandCost ret = Command::Do(flags, start_tile, 0, 0, {}); if (ret.Failed()) return ret; /* XXX - do NOT change 'ret' in the loop, as it is used as the price @@ -733,7 +735,7 @@ CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, uint32 p1, if (HasTileWaterGround(end_tile)) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER); /* Clear the tile in any case */ - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, end_tile, 0, 0); + ret = Command::Do(flags, end_tile, 0, 0, {}); if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND); cost.AddCost(ret); @@ -765,7 +767,7 @@ CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, uint32 p1, assert(coa_index < UINT_MAX); // more than 2**32 cleared areas would be a bug in itself coa = nullptr; - ret = DoCommand(flags, CMD_TERRAFORM_LAND, end_tile, end_tileh & start_tileh, 0); + ret = Command::Do(flags, end_tile, end_tileh & start_tileh, 0, {}); _cleared_object_areas[(uint)coa_index].first_tile = old_first_tile; if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND); cost.AddCost(ret); @@ -1847,7 +1849,7 @@ static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner if (tt == TRANSPORT_RAIL) { /* Since all of our vehicles have been removed, it is safe to remove the rail * bridge / tunnel. */ - [[maybe_unused]] CommandCost ret = DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + [[maybe_unused]] CommandCost ret = Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); assert(ret.Succeeded()); } else { /* In any other case, we can safely reassign the ownership to OWNER_NONE. */ @@ -2038,7 +2040,7 @@ static CommandCost TerraformTile_TunnelBridge(TileIndex tile, DoCommandFlag flag if (res.Succeeded() && (z_old == z_new) && (tileh_old == tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(flags, tile, 0, 0, {}); } extern const TileTypeProcs _tile_type_tunnelbridge_procs = { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 82170ed4c0..f09edc9095 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -51,6 +51,10 @@ #include "linkgraph/linkgraph.h" #include "linkgraph/refresh.h" #include "framerate_type.h" +#include "autoreplace_cmd.h" +#include "misc_cmd.h" +#include "train_cmd.h" +#include "vehicle_cmd.h" #include "table/strings.h" @@ -307,7 +311,7 @@ void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRF SetDParamStr(0, grfconfig->GetName()); SetDParam(1, engine); ShowErrorMessage(part1, part2, WL_CRITICAL); - if (!_networking) DoCommand(DC_EXEC, CMD_PAUSE, 0, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, 1); + if (!_networking) Command::Do(DC_EXEC, 0, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, 1, {}); } /* debug output */ @@ -1055,7 +1059,7 @@ void CallVehicleTicks() const Company *c = Company::Get(_current_company); SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money)); - CommandCost res = DoCommand(DC_EXEC, CMD_AUTOREPLACE_VEHICLE, 0, v->index, 0); + CommandCost res = Command::Do(DC_EXEC, 0, v->index, 0, {}); SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money)); if (!IsLocalCompany()) continue; @@ -1561,7 +1565,7 @@ void VehicleEnterDepot(Vehicle *v) if (v->current_order.IsRefit()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - CommandCost cost = DoCommand(DC_EXEC, CMD_REFIT_VEHICLE, v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8); + CommandCost cost = Command::Do(DC_EXEC, v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8, {}); cur_company.Restore(); if (cost.Failed()) { @@ -2443,7 +2447,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) /* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */ if (this->type == VEH_TRAIN && (reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) { - DoCommand(DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION, this->tile, this->index, 0); + Command::Do(DC_EXEC, this->tile, this->index, 0, {}); } if (this->type == VEH_AIRCRAFT) { diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index fe400bdab2..aeaefe68f4 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -32,6 +32,9 @@ #include "core/random_func.hpp" #include "vehicle_cmd.h" #include "aircraft_cmd.h" +#include "autoreplace_cmd.h" +#include "group_cmd.h" +#include "order_cmd.h" #include "roadveh_cmd.h" #include "train_cmd.h" #include "ship_cmd.h" @@ -180,7 +183,7 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint /* If we are not in DC_EXEC undo everything */ if (flags != subflags) { - DoCommand(DC_EXEC, CMD_SELL_VEHICLE, 0, v->index, 0); + Command::Do(DC_EXEC, 0, v->index, 0, {}); } } @@ -661,7 +664,7 @@ CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 if (!vehicle_list_window && !v->IsChainInDepot()) continue; /* Just try and don't care if some vehicle's can't be stopped. */ - DoCommand(flags, CMD_START_STOP_VEHICLE, tile, v->index, 0); + Command::Do(flags, tile, v->index, 0, {}); } return CommandCost(); @@ -691,7 +694,7 @@ CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, uint32 CommandCost last_error = CMD_ERROR; bool had_success = false; for (uint i = 0; i < list.size(); i++) { - CommandCost ret = DoCommand(flags, CMD_SELL_VEHICLE, tile, list[i]->index | (1 << 20), 0); + CommandCost ret = Command::Do(flags, tile, list[i]->index | (1 << 20), 0, {}); if (ret.Succeeded()) { cost.AddCost(ret); had_success = true; @@ -730,7 +733,7 @@ CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, uint32 /* Ensure that the vehicle completely in the depot */ if (!v->IsChainInDepot()) continue; - CommandCost ret = DoCommand(flags, CMD_AUTOREPLACE_VEHICLE, 0, v->index, 0); + CommandCost ret = Command::Do(flags, 0, v->index, 0, {}); if (ret.Succeeded()) cost.AddCost(ret); } @@ -869,11 +872,11 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint DoCommandFlag build_flags = flags; if ((flags & DC_EXEC) && !v->IsPrimaryVehicle()) build_flags |= DC_AUTOREPLACE; - CommandCost cost = DoCommand(build_flags, CMD_BUILD_VEHICLE, tile, v->engine_type | (1 << 16) | (CT_INVALID << 24), 0); + CommandCost cost = Command::Do(build_flags, tile, v->engine_type | (1 << 16) | (CT_INVALID << 24), 0, {}); if (cost.Failed()) { /* Can't build a part, then sell the stuff we already made; clear up the mess */ - if (w_front != nullptr) DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w_front->index | (1 << 20), 0); + if (w_front != nullptr) Command::Do(flags, w_front->tile, w_front->index | (1 << 20), 0, {}); return cost; } @@ -889,12 +892,12 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint if (v->type == VEH_TRAIN && !v->IsFrontEngine()) { /* this s a train car * add this unit to the end of the train */ - CommandCost result = DoCommand(flags, CMD_MOVE_RAIL_VEHICLE, 0, w->index | 1 << 20, w_rear->index); + CommandCost result = Command::Do(flags, 0, w->index | 1 << 20, w_rear->index, {}); if (result.Failed()) { /* The train can't be joined to make the same consist as the original. * Sell what we already made (clean up) and return an error. */ - DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w_front->index | 1 << 20, 0); - DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w->index | 1 << 20, 0); + Command::Do(flags, w_front->tile, w_front->index | 1 << 20, 0, {}); + Command::Do(flags, w_front->tile, w->index | 1 << 20, 0, {}); return result; // return error and the message returned from CMD_MOVE_RAIL_VEHICLE } } else { @@ -915,7 +918,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint if (flags & DC_EXEC) { /* Cloned vehicles belong to the same group */ - DoCommand(flags, CMD_ADD_VEHICLE_GROUP, 0, v_front->group_id, w_front->index); + Command::Do(flags, 0, v_front->group_id, w_front->index, {}); } @@ -937,7 +940,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint /* Find out what's the best sub type */ byte subtype = GetBestFittingSubType(v, w, v->cargo_type); if (w->cargo_type != v->cargo_type || w->cargo_subtype != subtype) { - CommandCost cost = DoCommand(flags, CMD_REFIT_VEHICLE, 0, w->index, v->cargo_type | 1U << 25 | (subtype << 8)); + CommandCost cost = Command::Do(flags, 0, w->index, v->cargo_type | 1U << 25 | (subtype << 8), {}); if (cost.Succeeded()) total_cost.AddCost(cost); } @@ -972,10 +975,10 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint * the vehicle refitted before doing this, otherwise the moved * cargo types might not match (passenger vs non-passenger) */ - CommandCost result = DoCommand(flags, CMD_CLONE_ORDER, 0, w_front->index | (p2 & 1 ? CO_SHARE : CO_COPY) << 30, v_front->index); + CommandCost result = Command::Do(flags, 0, w_front->index | (p2 & 1 ? CO_SHARE : CO_COPY) << 30, v_front->index, {}); if (result.Failed()) { /* The vehicle has already been bought, so now it must be sold again. */ - DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w_front->index | 1 << 20, 0); + Command::Do(flags, w_front->tile, w_front->index | 1 << 20, 0, {}); return result; } @@ -986,7 +989,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint * check whether the company has enough money manually. */ if (!CheckCompanyHasMoney(total_cost)) { /* The vehicle has already been bought, so now it must be sold again. */ - DoCommand(flags, CMD_SELL_VEHICLE, w_front->tile, w_front->index | 1 << 20, 0); + Command::Do(flags, w_front->tile, w_front->index | 1 << 20, 0, {}); return total_cost; } } @@ -1011,7 +1014,7 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con bool had_success = false; for (uint i = 0; i < list.size(); i++) { const Vehicle *v = list[i]; - CommandCost ret = DoCommand(flags, CMD_SEND_VEHICLE_TO_DEPOT, v->tile, v->index | (service ? DEPOT_SERVICE : 0U) | DEPOT_DONT_CANCEL, 0); + CommandCost ret = Command::Do(flags, v->tile, v->index | (service ? DEPOT_SERVICE : 0U) | DEPOT_DONT_CANCEL, 0, {}); if (ret.Succeeded()) { had_success = true; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index cac1985b96..d5d6978cc5 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -37,6 +37,7 @@ #include "tilehighlight_func.h" #include "zoom_func.h" #include "depot_cmd.h" +#include "vehicle_cmd.h" #include "safeguards.h" @@ -773,8 +774,8 @@ struct RefitWindow : public Window { { assert(_current_company == _local_company); Vehicle *v = Vehicle::Get(this->window_number); - CommandCost cost = DoCommand(DC_QUERY_COST, CMD_REFIT_VEHICLE, v->tile, this->selected_vehicle, option->cargo | - option->subtype << 8 | this->num_vehicles << 16 | (int)this->auto_refit << 24); + CommandCost cost = Command::Do(DC_QUERY_COST, v->tile, this->selected_vehicle, option->cargo | + option->subtype << 8 | this->num_vehicles << 16 | (int)this->auto_refit << 24, {}); if (cost.Failed()) return INVALID_STRING_ID; diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 6e357f9c68..07c13adcda 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -39,6 +39,7 @@ #include "newgrf_generic.h" #include "industry.h" #include "water_cmd.h" +#include "landscape_cmd.h" #include "table/strings.h" @@ -123,13 +124,13 @@ CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, ui CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_DEPOT_SHIP]); bool add_cost = !IsWaterTile(tile); - CommandCost ret = DoCommand(flags | DC_AUTO, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + CommandCost ret = Command::Do(flags | DC_AUTO, tile, 0, 0, {}); if (ret.Failed()) return ret; if (add_cost) { cost.AddCost(ret); } add_cost = !IsWaterTile(tile2); - ret = DoCommand(flags | DC_AUTO, CMD_LANDSCAPE_CLEAR, tile2, 0, 0); + ret = Command::Do(flags | DC_AUTO, tile2, 0, 0, {}); if (ret.Failed()) return ret; if (add_cost) { cost.AddCost(ret); @@ -307,13 +308,13 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag /* middle tile */ WaterClass wc_middle = HasTileWaterGround(tile) ? GetWaterClass(tile) : WATER_CLASS_CANAL; - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + ret = Command::Do(flags, tile, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); /* lower tile */ if (!IsWaterTile(tile - delta)) { - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile - delta, 0, 0); + ret = Command::Do(flags, tile - delta, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); cost.AddCost(_price[PR_BUILD_CANAL]); @@ -325,7 +326,7 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag /* upper tile */ if (!IsWaterTile(tile + delta)) { - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile + delta, 0, 0); + ret = Command::Do(flags, tile + delta, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); cost.AddCost(_price[PR_BUILD_CANAL]); @@ -481,7 +482,7 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Outside the editor, prevent building canals over your own or OWNER_NONE owned canals */ if (water && IsCanal(current_tile) && _game_mode != GM_EDITOR && (IsTileOwner(current_tile, _current_company) || IsTileOwner(current_tile, OWNER_NONE))) continue; - ret = DoCommand(flags, CMD_LANDSCAPE_CLEAR, current_tile, 0, 0); + ret = Command::Do(flags, current_tile, 0, 0, {}); if (ret.Failed()) return ret; if (!water) cost.AddCost(ret); @@ -1136,7 +1137,7 @@ void DoFloodTile(TileIndex target) FALLTHROUGH; case MP_CLEAR: - if (DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, target, 0, 0).Succeeded()) { + if (Command::Do(DC_EXEC, target, 0, 0, {}).Succeeded()) { MakeShore(target); MarkTileDirtyByTile(target); flooded = true; @@ -1151,7 +1152,7 @@ void DoFloodTile(TileIndex target) FloodVehicles(target); /* flood flat tile */ - if (DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, target, 0, 0).Succeeded()) { + if (Command::Do(DC_EXEC, target, 0, 0, {}).Succeeded()) { MakeSea(target); MarkTileDirtyByTile(target); flooded = true; @@ -1203,7 +1204,7 @@ static void DoDryUp(TileIndex tile) case MP_WATER: assert(IsCoast(tile)); - if (DoCommand(DC_EXEC, CMD_LANDSCAPE_CLEAR, tile, 0, 0).Succeeded()) { + if (Command::Do(DC_EXEC, tile, 0, 0, {}).Succeeded()) { MakeClear(tile, CLEAR_GRASS, 3); MarkTileDirtyByTile(tile); } @@ -1362,7 +1363,7 @@ static void ChangeTileOwner_Water(TileIndex tile, Owner old_owner, Owner new_own } /* Remove depot */ - if (IsShipDepot(tile)) DoCommand(DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + if (IsShipDepot(tile)) Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); /* Set owner of canals and locks ... and also canal under dock there was before. * Check if the new owner after removing depot isn't OWNER_WATER. */ @@ -1382,7 +1383,7 @@ static CommandCost TerraformTile_Water(TileIndex tile, DoCommandFlag flags, int /* Canals can't be terraformed */ if (IsWaterTile(tile) && IsCanal(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST); - return DoCommand(flags, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + return Command::Do(DC_EXEC, tile, 0, 0, {}); } diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index a95d5c9540..a3edf71e89 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -29,6 +29,7 @@ #include "water.h" #include "company_gui.h" #include "waypoint_cmd.h" +#include "landscape_cmd.h" #include "table/strings.h" @@ -316,7 +317,7 @@ CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_WAYPOINT_BUOY]); if (!IsWaterTile(tile)) { - CommandCost ret = DoCommand(flags | DC_AUTO, CMD_LANDSCAPE_CLEAR, tile, 0, 0); + CommandCost ret = Command::Do(flags | DC_AUTO, tile, 0, 0, {}); if (ret.Failed()) return ret; cost.AddCost(ret); } From 0f64ee5ce1548d9cda69917f27c5b1a3cb91823d Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 31 Oct 2021 19:39:09 +0100 Subject: [PATCH 16/60] Codechange: Template DoCommandP to automagically reflect the parameters of the command proc. When finished, this will allow each command handler to take individually different parameters, obliviating the need for bit-packing. --- src/ai/ai_gui.cpp | 10 +- src/airport_gui.cpp | 2 +- src/autoreplace_gui.cpp | 13 ++- src/bridge_gui.cpp | 6 +- src/build_vehicle_gui.cpp | 7 +- src/cheat_gui.cpp | 3 +- src/command.cpp | 146 ++++++---------------------- src/command_func.h | 87 +++++++++++++++-- src/company_cmd.cpp | 2 +- src/company_gui.cpp | 29 +++--- src/console_cmds.cpp | 16 +-- src/depot_gui.cpp | 23 +++-- src/dock_gui.cpp | 16 +-- src/economy.cpp | 3 +- src/engine_gui.cpp | 3 +- src/fios_gui.cpp | 5 +- src/goal_gui.cpp | 7 +- src/group_gui.cpp | 25 ++--- src/highscore_gui.cpp | 9 +- src/industry_gui.cpp | 7 +- src/linkgraph/linkgraphschedule.cpp | 5 +- src/main_gui.cpp | 3 +- src/misc_cmd.cpp | 2 +- src/network/network.cpp | 2 +- src/network/network_command.cpp | 2 +- src/network/network_gui.cpp | 5 +- src/network/network_server.cpp | 5 +- src/object_gui.cpp | 5 +- src/openttd.cpp | 9 +- src/order_backup.cpp | 2 +- src/order_gui.cpp | 45 ++++----- src/rail_gui.cpp | 61 +++++++----- src/road_gui.cpp | 29 +++--- src/settings.cpp | 4 +- src/signs_cmd.cpp | 2 +- src/signs_gui.cpp | 3 +- src/station_gui.cpp | 5 +- src/story_gui.cpp | 7 +- src/terraform_gui.cpp | 18 ++-- src/timetable_gui.cpp | 13 +-- src/toolbar_gui.cpp | 3 +- src/town_gui.cpp | 11 ++- src/train_cmd.cpp | 3 +- src/train_gui.cpp | 3 +- src/tree_gui.cpp | 5 +- src/vehicle_gui.cpp | 31 +++--- src/waypoint_gui.cpp | 3 +- 47 files changed, 374 insertions(+), 331 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 340b6db956..5996039c9d 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -28,6 +28,8 @@ #include "../hotkeys.h" #include "../core/geometry_func.hpp" #include "../guitimer_func.h" +#include "../company_cmd.h" +#include "../misc_cmd.h" #include "ai.hpp" #include "ai_gui.hpp" @@ -1290,8 +1292,8 @@ struct AIDebugWindow : public Window { case WID_AID_RELOAD_TOGGLE: if (ai_debug_company == OWNER_DEITY) break; /* First kill the company of the AI, then start a new one. This should start the current AI again */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | ai_debug_company << 16 | CRR_MANUAL << 24, 0); - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | ai_debug_company << 16, 0); + Command::Post(0, CCA_DELETE | ai_debug_company << 16 | CRR_MANUAL << 24, 0, {}); + Command::Post(0, CCA_NEW_AI | ai_debug_company << 16, 0, {}); break; case WID_AID_SETTINGS: @@ -1330,7 +1332,7 @@ struct AIDebugWindow : public Window { } if (all_unpaused) { /* All scripts have been unpaused => unpause the game. */ - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); + Command::Post(0, PM_PAUSED_NORMAL, 0, {}); } } } @@ -1379,7 +1381,7 @@ struct AIDebugWindow : public Window { /* Pause the game. */ if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + Command::Post(0, PM_PAUSED_NORMAL, 1, {}); } /* Highlight row that matched */ diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 98776e52fd..af1fb1309f 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -71,7 +71,7 @@ static void PlaceAirport(TileIndex tile) uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_AIRPORT, STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, tile, p1, p2_final); + return Command::Post(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, tile, p1, p2_final, {}); } }; diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index d4e392c971..c5cfd04cb6 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -25,6 +25,9 @@ #include "rail_gui.h" #include "road_gui.h" #include "widgets/dropdown_func.h" +#include "autoreplace_cmd.h" +#include "group_cmd.h" +#include "settings_cmd.h" #include "widgets/autoreplace_widget.h" @@ -217,7 +220,7 @@ class ReplaceVehicleWindow : public Window { { EngineID veh_from = this->sel_engine[0]; EngineID veh_to = this->sel_engine[1]; - DoCommandP(CMD_SET_AUTOREPLACE, 0, (replace_when_old ? 1 : 0) | (this->sel_group << 16), veh_from + (veh_to << 16)); + Command::Post(0, (replace_when_old ? 1 : 0) | (this->sel_group << 16), veh_from + (veh_to << 16), {}); } public: @@ -541,10 +544,10 @@ public: case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: { const Group *g = Group::GetIfValid(this->sel_group); if (g != nullptr) { - DoCommandP(CMD_SET_GROUP_FLAG, 0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1)); + Command::Post(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), {}); } else { // toggle renew_keep_length - DoCommandP(CMD_CHANGE_COMPANY_SETTING, 0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, "company.renew_keep_length"); + Command::Post(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, "company.renew_keep_length"); } break; } @@ -562,7 +565,7 @@ public: case WID_RV_STOP_REPLACE: { // Stop replacing EngineID veh_from = this->sel_engine[0]; - DoCommandP(CMD_SET_AUTOREPLACE, 0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16)); + Command::Post(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), {}); break; } @@ -584,7 +587,7 @@ public: if (click_side == 0 && _ctrl_pressed && e != INVALID_ENGINE && (GetGroupNumEngines(_local_company, sel_group, e) == 0 || GetGroupNumEngines(_local_company, ALL_GROUP, e) == 0)) { EngineID veh_from = e; - DoCommandP(CMD_SET_AUTOREPLACE, 0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16)); + Command::Post(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), {}); break; } diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index abd1f3da54..e9e1f48f5a 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -119,8 +119,8 @@ private: case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->at(i).index; break; default: break; } - DoCommandP(CMD_BUILD_BRIDGE, STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, - this->end_tile, this->start_tile, this->type | this->bridges->at(i).index); + Command::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, + this->end_tile, this->start_tile, this->type | this->bridges->at(i).index, {}); } /** Sort the builable bridges */ @@ -385,7 +385,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo default: break; // water ways and air routes don't have bridge types } if (_ctrl_pressed && CheckBridgeAvailability(last_bridge_type, bridge_len).Succeeded()) { - DoCommandP(CMD_BUILD_BRIDGE, STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, type | last_bridge_type); + Command::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, type | last_bridge_type, {}); return; } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 9082de5a97..639bab7a9f 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -30,6 +30,7 @@ #include "cargotype.h" #include "core/geometry_func.hpp" #include "autoreplace_func.h" +#include "engine_cmd.h" #include "train_cmd.h" #include "vehicle_cmd.h" @@ -1460,7 +1461,7 @@ struct BuildVehicleWindow : Window { case WID_BV_SHOW_HIDE: { const Engine *e = (this->sel_engine == INVALID_ENGINE) ? nullptr : Engine::Get(this->sel_engine); if (e != nullptr) { - DoCommandP(CMD_SET_VEHICLE_VISIBILITY, 0, 0, this->sel_engine | (e->IsHidden(_current_company) ? 0 : (1u << 31))); + Command::Post(0, 0, this->sel_engine | (e->IsHidden(_current_company) ? 0 : (1u << 31)), {}); } break; } @@ -1471,7 +1472,7 @@ struct BuildVehicleWindow : Window { CommandCallback *callback = (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildPrimaryVehicle; CargoID cargo = this->cargo_filter[this->cargo_filter_criteria]; if (cargo == CF_ANY || cargo == CF_ENGINES) cargo = CF_NONE; - DoCommandP(CMD_BUILD_VEHICLE, GetCmdBuildVehMsg(this->vehicle_type), callback, this->window_number, sel_eng | (cargo << 24), 0); + Command::Post(GetCmdBuildVehMsg(this->vehicle_type), callback, this->window_number, sel_eng | (cargo << 24), 0, {}); } break; } @@ -1636,7 +1637,7 @@ struct BuildVehicleWindow : Window { { if (str == nullptr) return; - DoCommandP(CMD_RENAME_ENGINE, STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, 0, this->rename_engine, 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, 0, this->rename_engine, 0, str); } void OnDropdownSelect(int widget, int index) override diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 84884b3ded..fcc9a3ef07 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -28,6 +28,7 @@ #include "tile_map.h" #include "newgrf.h" #include "error.h" +#include "misc_cmd.h" #include "widgets/cheat_widget.h" @@ -54,7 +55,7 @@ static int32 _money_cheat_amount = 10000000; */ static int32 ClickMoneyCheat(int32 p1, int32 p2) { - DoCommandP(CMD_MONEY_CHEAT, 0, (uint32)(p2 * _money_cheat_amount), 0); + Command::Post(0, (uint32)(p2 * _money_cheat_amount), 0, {}); return _money_cheat_amount; } diff --git a/src/command.cpp b/src/command.cpp index 69cbaa6c92..dc536a843c 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -213,51 +213,50 @@ void CommandHelperBase::InternalDoAfter(CommandCost &res, DoCommandFlag flags, b } } -/*! - * Toplevel network safe docommand function for the current company. Must not be called recursively. - * The callback is called when the command succeeded or failed. The parameters - * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. - * The parameter \a my_cmd is used to indicate if the command is from a company or the server. - * - * @param cmd The command to execute (a CMD_* value) - * @param callback A callback function to call after the command is finished - * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) - * @param network_command execute the command without sending it on the network - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. +/** + * Decide what to do with the command depending on current game state. + * @param cmd Command to execute. + * @param flags Command flags. + * @param tile Tile of command execution. + * @param err_message Message prefix to show on error. + * @param network_command Does this command come from the network? + * @return error state + do only cost estimation? + send to network only? */ -static bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +std::tuple CommandHelperBase::InternalPostBefore(Commands cmd, CommandFlags flags, TileIndex tile, StringID err_message, bool network_command) { /* Cost estimation is generally only done when the * local user presses shift while doing something. * However, in case of incoming network commands, * map generation or the pause button we do want * to execute. */ - bool estimate_only = _shift_pressed && IsLocalCompany() && - !_generating_world && - !network_command && - !(GetCommandFlags(cmd) & CMD_NO_EST); + bool estimate_only = _shift_pressed && IsLocalCompany() && !_generating_world && !network_command && !(flags & CMD_NO_EST); /* We're only sending the command, so don't do * fancy things for 'success'. */ bool only_sending = _networking && !network_command; - /* Where to show the message? */ - int x = TileX(tile) * TILE_SIZE; - int y = TileY(tile) * TILE_SIZE; - if (_pause_mode != PM_UNPAUSED && !IsCommandAllowedWhilePaused(cmd) && !estimate_only) { - ShowErrorMessage(err_message, STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, x, y); - return false; + ShowErrorMessage(err_message, STR_ERROR_NOT_ALLOWED_WHILE_PAUSED, WL_INFO, TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE); + return { true, estimate_only, only_sending }; + } else { + return { false, estimate_only, only_sending }; } +} - /* Only set p2 when the command does not come from the network. */ - if (!network_command && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER; +/** + * Process result of executing a command, possibly displaying any error to the player. + * @param res Command result. + * @param tile Tile of command execution. + * @param estimate_only Is this just cost estimation? + * @param only_sending Was the command only sent to network? + * @param err_message Message prefix to show on error. + * @param my_cmd Is the command from this client? + */ +void CommandHelperBase::InternalPostResult(const CommandCost &res, TileIndex tile, bool estimate_only, bool only_sending, StringID err_message, bool my_cmd) +{ + int x = TileX(tile) * TILE_SIZE; + int y = TileY(tile) * TILE_SIZE; - CommandCost res = DoCommandPInternal(cmd, err_message, callback, my_cmd, estimate_only, network_command, tile, p1, p2, text); if (res.Failed()) { /* Only show the error when it's for us. */ if (estimate_only || (IsLocalCompany() && err_message != 0 && my_cmd)) { @@ -273,95 +272,6 @@ static bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *call * concept of cost, so don't show it there either. */ ShowCostOrIncomeAnimation(x, y, GetSlopePixelZ(x, y), res.GetCost()); } - - if (!estimate_only && !only_sending && callback != nullptr) { - callback(res, cmd, tile, p1, p2, text); - } - - return res.Succeeded(); -} - -/** - * Shortcut for the long DoCommandP when not using a callback or error message. - * @param cmd The command to execute (a CMD_* value) - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool DoCommandP(Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, STR_NULL, nullptr, true, false, tile, p1, p2, text); -} - -/** - * Shortcut for the long DoCommandP when not using an error message. - * @param cmd The command to execute (a CMD_* value) - * @param callback A callback function to call after the command is finished - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool DoCommandP(Commands cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, STR_NULL, callback, true, false, tile, p1, p2, text); -} - -/** - * Shortcut for the long DoCommandP when not using a callback. - * @param cmd The command to execute (a CMD_* value) - * @param err_message Message prefix to show on error - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool DoCommandP(Commands cmd, StringID err_message, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, err_message, nullptr, true, false, tile, p1, p2, text); -} - -/*! - * Toplevel network safe docommand function for the current company. Must not be called recursively. - * The callback is called when the command succeeded or failed. The parameters - * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. - * - * @param cmd The command to execute (a CMD_* value) - * @param err_message Message prefix to show on error - * @param callback A callback function to call after the command is finished - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, err_message, callback, true, false, tile, p1, p2, text); -} - -/** - * Toplevel network safe docommand function for the current company. Must not be called recursively. - * The callback is called when the command succeeded or failed. The parameters - * \a tile, \a p1, and \a p2 are from the #CommandProc function. The parameter \a cmd is the command to execute. - * - * @param cmd The command to execute (a CMD_* value) - * @param err_message Message prefix to show on error - * @param callback A callback function to call after the command is finished - * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return \c true if the command succeeded, else \c false. - */ -bool InjectNetworkCommand(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - return DoCommandP(cmd, err_message, callback, my_cmd, true, tile, p1, p2, text); } /** Helper to format command parameters into a hex string. */ diff --git a/src/command_func.h b/src/command_func.h index 1c24221cd2..6a9b93ff54 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -37,14 +37,6 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); /** Storage buffer for serialized command data. */ typedef std::vector CommandDataBuffer; - -bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -bool DoCommandP(Commands cmd, StringID err_message, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -bool DoCommandP(Commands cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); -bool DoCommandP(Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {}); - -bool InjectNetworkCommand(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); - CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); @@ -96,6 +88,8 @@ class CommandHelperBase { protected: static void InternalDoBefore(bool top_level, bool test); static void InternalDoAfter(CommandCost &res, DoCommandFlag flags, bool top_level, bool test); + static std::tuple InternalPostBefore(Commands cmd, CommandFlags flags, TileIndex tile, StringID err_message, bool network_command); + static void InternalPostResult(const CommandCost &res, TileIndex tile, bool estimate_only, bool only_sending, StringID err_message, bool my_cmd); }; /** @@ -147,6 +141,83 @@ public: return res; } + + /** + * Shortcut for the long Post when not using a callback. + * @param err_message Message prefix to show on error + * @param args Parameters for the command + */ + static inline bool Post(StringID err_message, Targs... args) { return Post(err_message, nullptr, std::forward(args)...); } + /** + * Shortcut for the long Post when not using an error message. + * @param callback A callback function to call after the command is finished + * @param args Parameters for the command + */ + static inline bool Post(CommandCallback *callback, Targs... args) { return Post((StringID)0, callback, std::forward(args)...); } + /** + * Shortcut for the long Post when not using a callback or an error message. + * @param args Parameters for the command + */ + static inline bool Post(Targs... args) { return Post((StringID)0, nullptr, std::forward(args)...); } + + /** + * Top-level network safe command execution for the current company. + * Must not be called recursively. The callback is called when the + * command succeeded or failed. + * + * @param err_message Message prefix to show on error + * @param callback A callback function to call after the command is finished + * @param args Parameters for the command + * @return \c true if the command succeeded, else \c false. + */ + static bool Post(StringID err_message, CommandCallback *callback, Targs... args) + { + return InternalPost(err_message, callback, true, false, std::forward_as_tuple(args...)); + } + + /** + * Execute a command coming from the network. + * @param err_message Message prefix to show on error + * @param callback A callback function to call after the command is finished + * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) + * @param location Tile location for user feedback. + * @param args Parameters for the command + * @return \c true if the command succeeded, else \c false. + */ + static bool PostFromNet(StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex location, std::tuple args) + { + return InternalPost(err_message, callback, my_cmd, true, location, std::move(args)); + } + +protected: + static bool InternalPost(StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, std::tuple args) + { + /* Where to show the message? */ + TileIndex tile{}; + if constexpr (std::is_same_v>) { + tile = std::get<0>(args); + } + + return InternalPost(err_message, callback, my_cmd, network_command, tile, std::move(args)); + } + + static bool InternalPost(StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, TileIndex tile, std::tuple args) + { + auto [err, estimate_only, only_sending] = InternalPostBefore(Tcmd, GetCommandFlags(), tile, err_message, network_command); + if (err) return false; + + /* Only set p2 when the command does not come from the network. */ + if (!network_command && GetCommandFlags() & CMD_CLIENT_ID && std::get<2>(args) == 0) std::get<2>(args) = CLIENT_ID_SERVER; + + CommandCost res = std::apply(DoCommandPInternal, std::tuple_cat(std::make_tuple(Tcmd, err_message, callback, my_cmd, estimate_only, network_command), args)); + InternalPostResult(res, tile, estimate_only, only_sending, err_message, my_cmd); + + if (!estimate_only && !only_sending && callback != nullptr) { + std::apply(callback, std::tuple_cat(std::tuple{ res, Tcmd }, args)); + } + + return res.Succeeded(); + } }; template diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 6bd60659b7..cf44af25c7 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -604,7 +604,7 @@ static bool MaybeStartNewCompany() if (n < (uint)_settings_game.difficulty.max_no_competitors) { /* Send a command to all clients to start up a new AI. * Works fine for Multiplayer and Singleplayer */ - return DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | INVALID_COMPANY << 16, 0); + return Command::Post(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, {}); } return false; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 7a6e68dea7..c2695b9105 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -37,6 +37,11 @@ #include "station_func.h" #include "zoom_func.h" #include "sortlist_type.h" +#include "company_cmd.h" +#include "economy_cmd.h" +#include "group_cmd.h" +#include "misc_cmd.h" +#include "object_cmd.h" #include "widgets/company_widget.h" @@ -435,11 +440,11 @@ struct CompanyFinancesWindow : Window { break; case WID_CF_INCREASE_LOAN: // increase loan - DoCommandP(CMD_INCREASE_LOAN, STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY, 0, 0, _ctrl_pressed); + Command::Post(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY, 0, 0, _ctrl_pressed, {}); break; case WID_CF_REPAY_LOAN: // repay loan - DoCommandP(CMD_DECREASE_LOAN, STR_ERROR_CAN_T_REPAY_LOAN, 0, 0, _ctrl_pressed); + Command::Post(STR_ERROR_CAN_T_REPAY_LOAN, 0, 0, _ctrl_pressed, {}); break; case WID_CF_INFRASTRUCTURE: // show infrastructure details @@ -995,12 +1000,12 @@ public: for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) { /* Changed colour for the selected scheme, or all visible schemes if CTRL is pressed. */ if (HasBit(this->sel, scheme) || (_ctrl_pressed && _livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme))) { - DoCommandP(CMD_SET_COMPANY_COLOUR, 0, scheme | (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256), index); + Command::Post(0, scheme | (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256), index, {}); } } } else { /* Setting group livery */ - DoCommandP(CMD_SET_GROUP_LIVERY, 0, this->sel, (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256) | (index << 16)); + Command::Post(0, this->sel, (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256) | (index << 16), {}); } } @@ -1581,7 +1586,7 @@ public: /* OK button */ case WID_SCMF_ACCEPT: - DoCommandP(CMD_SET_COMPANY_MANAGER_FACE, 0, 0, this->face); + Command::Post(0, 0, this->face, {}); FALLTHROUGH; /* Cancel button */ @@ -2576,11 +2581,11 @@ struct CompanyWindow : Window break; case WID_C_BUY_SHARE: - DoCommandP(CMD_BUY_SHARE_IN_COMPANY, STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, (TileIndex)0, this->window_number, 0); + Command::Post(STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, 0, this->window_number, 0, {}); break; case WID_C_SELL_SHARE: - DoCommandP(CMD_SELL_SHARE_IN_COMPANY, STR_ERROR_CAN_T_SELL_25_SHARE_IN, (TileIndex)0, this->window_number, 0); + Command::Post(STR_ERROR_CAN_T_SELL_25_SHARE_IN, 0, this->window_number, 0, {}); break; case WID_C_COMPANY_PASSWORD: @@ -2613,7 +2618,7 @@ struct CompanyWindow : Window void OnPlaceObject(Point pt, TileIndex tile) override { - if (DoCommandP(CMD_BUILD_OBJECT, STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS, tile, OBJECT_HQ, 0) && !_shift_pressed) { + if (Command::Post(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS, tile, OBJECT_HQ, 0, {}) && !_shift_pressed) { ResetObjectToPlace(); this->RaiseButtons(); } @@ -2635,16 +2640,16 @@ struct CompanyWindow : Window Money money = (Money)(strtoull(str, nullptr, 10) / _currency->rate); uint32 money_c = Clamp(ClampToI32(money), 0, 20000000); // Clamp between 20 million and 0 - DoCommandP(CMD_GIVE_MONEY, STR_ERROR_CAN_T_GIVE_MONEY, 0, money_c, this->window_number); + Command::Post(STR_ERROR_CAN_T_GIVE_MONEY, 0, money_c, this->window_number, {}); break; } case WID_C_PRESIDENT_NAME: - DoCommandP(CMD_RENAME_PRESIDENT, STR_ERROR_CAN_T_CHANGE_PRESIDENT, 0, 0, 0, str); + Command::Post(STR_ERROR_CAN_T_CHANGE_PRESIDENT, 0, 0, 0, str); break; case WID_C_COMPANY_NAME: - DoCommandP(CMD_RENAME_COMPANY, STR_ERROR_CAN_T_CHANGE_COMPANY_NAME, 0, 0, 0, str); + Command::Post(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME, 0, 0, 0, str); break; case WID_C_COMPANY_JOIN: @@ -2771,7 +2776,7 @@ struct BuyCompanyWindow : Window { break; case WID_BC_YES: - DoCommandP(CMD_BUY_COMPANY, STR_ERROR_CAN_T_BUY_COMPANY, (TileIndex)0, this->window_number, 0); + Command::Post(STR_ERROR_CAN_T_BUY_COMPANY, 0, this->window_number, 0, {}); break; } } diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 040b938fe7..42a94aa89f 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -42,6 +42,8 @@ #include "game/game.hpp" #include "table/strings.h" #include "walltime_func.h" +#include "company_cmd.h" +#include "misc_cmd.h" #include "safeguards.h" @@ -630,7 +632,7 @@ DEF_CONSOLE_CMD(ConPauseGame) } if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + Command::Post(0, PM_PAUSED_NORMAL, 1, {}); if (!_networking) IConsolePrint(CC_DEFAULT, "Game paused."); } else { IConsolePrint(CC_DEFAULT, "Game is already paused."); @@ -652,7 +654,7 @@ DEF_CONSOLE_CMD(ConUnpauseGame) } if ((_pause_mode & PM_PAUSED_NORMAL) != PM_UNPAUSED) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); + Command::Post(0, PM_PAUSED_NORMAL, 0, {}); if (!_networking) IConsolePrint(CC_DEFAULT, "Game unpaused."); } else if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED) { IConsolePrint(CC_DEFAULT, "Game is in error state and cannot be unpaused via console."); @@ -863,7 +865,7 @@ DEF_CONSOLE_CMD(ConResetCompany) } /* It is safe to remove this company */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0); + Command::Post(0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0, {}); IConsolePrint(CC_DEFAULT, "Company deleted."); return true; @@ -1220,7 +1222,7 @@ DEF_CONSOLE_CMD(ConStartAI) } /* Start a new AI company */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | INVALID_COMPANY << 16, 0); + Command::Post(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, {}); return true; } @@ -1256,8 +1258,8 @@ DEF_CONSOLE_CMD(ConReloadAI) } /* First kill the company of the AI, then start a new one. This should start the current AI again */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0); - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW_AI | company_id << 16, 0); + Command::Post(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, {}); + Command::Post(0, CCA_NEW_AI | company_id << 16, 0, {}); IConsolePrint(CC_DEFAULT, "AI reloaded."); return true; @@ -1294,7 +1296,7 @@ DEF_CONSOLE_CMD(ConStopAI) } /* Now kill the company of the AI. */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0); + Command::Post(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, {}); IConsolePrint(CC_DEFAULT, "AI stopped, company deleted."); return true; diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 0aba48e40c..76e03ef396 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -26,6 +26,9 @@ #include "vehiclelist.h" #include "order_backup.h" #include "zoom_func.h" +#include "depot_cmd.h" +#include "train_cmd.h" +#include "vehicle_cmd.h" #include "widgets/depot_widget.h" @@ -142,7 +145,7 @@ static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Veh if (wagon == v) return; - DoCommandP(CMD_MOVE_RAIL_VEHICLE, STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index); + Command::Post(STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index, {}); } static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END]; ///< Cell size for vehicle images in the depot view. @@ -803,7 +806,7 @@ struct DepotWindow : Window { case WID_D_STOP_ALL: case WID_D_START_ALL: { VehicleListIdentifier vli(VL_DEPOT_LIST, this->type, this->owner); - DoCommandP(CMD_MASS_START_STOP, this->window_number, (widget == WID_D_START_ALL ? (1 << 0) : 0), vli.Pack()); + Command::Post(this->window_number, (widget == WID_D_START_ALL ? (1 << 0) : 0), vli.Pack(), {}); break; } @@ -826,7 +829,7 @@ struct DepotWindow : Window { break; case WID_D_AUTOREPLACE: - DoCommandP(CMD_DEPOT_MASS_AUTOREPLACE, this->window_number, this->type, 0); + Command::Post(this->window_number, this->type, 0, {}); break; } @@ -837,7 +840,7 @@ struct DepotWindow : Window { if (str == nullptr) return; /* Do depot renaming */ - DoCommandP(CMD_RENAME_DEPOT, STR_ERROR_CAN_T_RENAME_DEPOT, 0, this->GetDepotIndex(), 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_DEPOT, 0, this->GetDepotIndex(), 0, str); } bool OnRightClick(Point pt, int widget) override @@ -905,10 +908,10 @@ struct DepotWindow : Window { { if (_ctrl_pressed) { /* Share-clone, do not open new viewport, and keep tool active */ - DoCommandP(CMD_CLONE_VEHICLE, STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, 1); + Command::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, 1, {}); } else { - /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to changs things on new vehicle) */ - if (DoCommandP(CMD_CLONE_VEHICLE, STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, 0)) { + /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to change things on new vehicle) */ + if (Command::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, 0, {})) { ResetObjectToPlace(); } } @@ -1002,7 +1005,7 @@ struct DepotWindow : Window { if (this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, &gdvp) == MODE_DRAG_VEHICLE && sel != INVALID_VEHICLE) { if (gdvp.wagon != nullptr && gdvp.wagon->index == sel && _ctrl_pressed) { - DoCommandP(CMD_REVERSE_TRAIN_DIRECTION, STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true); + Command::Post(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true, {}); } else if (gdvp.wagon == nullptr || gdvp.wagon->index != sel) { this->vehicle_over = INVALID_VEHICLE; TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head); @@ -1027,7 +1030,7 @@ struct DepotWindow : Window { this->SetDirty(); int sell_cmd = (v->type == VEH_TRAIN && (widget == WID_D_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0; - DoCommandP(CMD_SELL_VEHICLE, GetCmdSellVehMsg(v->type), v->tile, v->index | sell_cmd << 20 | MAKE_ORDER_BACKUP_FLAG, 0); + Command::Post(GetCmdSellVehMsg(v->type), v->tile, v->index | sell_cmd << 20 | MAKE_ORDER_BACKUP_FLAG, 0, {}); break; } @@ -1091,7 +1094,7 @@ static void DepotSellAllConfirmationCallback(Window *win, bool confirmed) DepotWindow *w = (DepotWindow*)win; TileIndex tile = w->window_number; byte vehtype = w->type; - DoCommandP(CMD_DEPOT_SELL_ALL_VEHICLES, tile, vehtype, 0); + Command::Post(tile, vehtype, 0, {}); } } diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 571bfdcec0..3cb101f7ad 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -28,6 +28,8 @@ #include "tunnelbridge_cmd.h" #include "dock_cmd.h" #include "station_cmd.h" +#include "water_cmd.h" +#include "waypoint_cmd.h" #include "widgets/dock_widget.h" @@ -194,7 +196,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_LOCK: // Build lock button - DoCommandP(CMD_BUILD_LOCK, STR_ERROR_CAN_T_BUILD_LOCKS, CcBuildDocks, tile, 0, 0); + Command::Post(STR_ERROR_CAN_T_BUILD_LOCKS, CcBuildDocks, tile, 0, 0, {}); break; case WID_DT_DEMOLISH: // Demolish aka dynamite button @@ -202,7 +204,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_DEPOT: // Build depot button - DoCommandP(CMD_BUILD_SHIP_DEPOT, STR_ERROR_CAN_T_BUILD_SHIP_DEPOT, CcBuildDocks, tile, _ship_depot_direction, 0); + Command::Post(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT, CcBuildDocks, tile, _ship_depot_direction, 0, {}); break; case WID_DT_STATION: { // Build station button @@ -220,7 +222,7 @@ struct BuildDocksToolbarWindow : Window { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_DOCK, STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, tile, p1, p2_final); + return Command::Post(STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, tile, p1, p2_final, {}); } }; @@ -229,7 +231,7 @@ struct BuildDocksToolbarWindow : Window { } case WID_DT_BUOY: // Build buoy button - DoCommandP(CMD_BUILD_BUOY, STR_ERROR_CAN_T_POSITION_BUOY_HERE, CcBuildDocks, tile, 0, 0); + Command::Post(STR_ERROR_CAN_T_POSITION_BUOY_HERE, CcBuildDocks, tile, 0, 0, {}); break; case WID_DT_RIVER: // Build river button (in scenario editor) @@ -237,7 +239,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button - DoCommandP(CMD_BUILD_BRIDGE, STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15); + Command::Post(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15, {}); break; default: NOT_REACHED(); @@ -257,10 +259,10 @@ struct BuildDocksToolbarWindow : Window { GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; case DDSP_CREATE_WATER: - DoCommandP(CMD_BUILD_CANAL, STR_ERROR_CAN_T_BUILD_CANALS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL); + Command::Post(STR_ERROR_CAN_T_BUILD_CANALS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL, {}); break; case DDSP_CREATE_RIVER: - DoCommandP(CMD_BUILD_CANAL, STR_ERROR_CAN_T_PLACE_RIVERS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0)); + Command::Post(STR_ERROR_CAN_T_PLACE_RIVERS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0), {}); break; default: break; diff --git a/src/economy.cpp b/src/economy.cpp index e7daf8e3d1..c65d997b80 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -48,6 +48,7 @@ #include "goal_base.h" #include "story_base.h" #include "linkgraph/refresh.h" +#include "company_cmd.h" #include "economy_cmd.h" #include "vehicle_cmd.h" @@ -629,7 +630,7 @@ static void CompanyCheckBankrupt(Company *c) * player we are sure (the above check) that we are not the local * company and thus we won't be moved. */ if (!_networking || _network_server) { - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | (c->index << 16) | (CRR_BANKRUPT << 24), 0); + Command::Post(0, CCA_DELETE | (c->index << 16) | (CRR_BANKRUPT << 24), 0, {}); return; } break; diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index 6710967f43..c3b9553a7e 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -23,6 +23,7 @@ #include "roadveh.h" #include "ship.h" #include "aircraft.h" +#include "engine_cmd.h" #include "widgets/engine_widget.h" @@ -125,7 +126,7 @@ struct EnginePreviewWindow : Window { { switch (widget) { case WID_EP_YES: - DoCommandP(CMD_WANT_ENGINE_PREVIEW, 0, this->window_number, 0); + Command::Post(0, this->window_number, 0, {}); FALLTHROUGH; case WID_EP_NO: if (!_shift_pressed) this->Close(); diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 9d7ab70d8c..73315edf0f 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -27,6 +27,7 @@ #include "core/geometry_func.hpp" #include "gamelog.h" #include "stringfilter_type.h" +#include "misc_cmd.h" #include "widgets/fios_widget.h" @@ -358,7 +359,7 @@ public: /* pause is only used in single-player, non-editor mode, non-menu mode. It * will be unpaused in the WE_DESTROY event handler. */ if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 1); + Command::Post(0, PM_PAUSED_SAVELOAD, 1, {}); } SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); @@ -402,7 +403,7 @@ public: { /* pause is only used in single-player, non-editor mode, non menu mode */ if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 0); + Command::Post(0, PM_PAUSED_SAVELOAD, 0, {}); } this->Window::Close(); } diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index d6180b0df2..ef63197d54 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -23,6 +23,7 @@ #include "story_base.h" #include "command_func.h" #include "string_func.h" +#include "goal_cmd.h" #include "widgets/goal_widget.h" @@ -382,17 +383,17 @@ struct GoalQuestionWindow : public Window { { switch (widget) { case WID_GQ_BUTTON_1: - DoCommandP(CMD_GOAL_QUESTION_ANSWER, 0, this->window_number, this->button[0]); + Command::Post(0, this->window_number, this->button[0], {}); this->Close(); break; case WID_GQ_BUTTON_2: - DoCommandP(CMD_GOAL_QUESTION_ANSWER, 0, this->window_number, this->button[1]); + Command::Post(0, this->window_number, this->button[1], {}); this->Close(); break; case WID_GQ_BUTTON_3: - DoCommandP(CMD_GOAL_QUESTION_ANSWER, 0, this->window_number, this->button[2]); + Command::Post(0, this->window_number, this->button[2], {}); this->Close(); break; } diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 8beab1884b..b2deba3091 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -26,6 +26,7 @@ #include "company_gui.h" #include "gui.h" #include "group_cmd.h" +#include "vehicle_cmd.h" #include "widgets/group_widget.h" @@ -641,7 +642,7 @@ public: if (confirmed) { VehicleGroupWindow *w = (VehicleGroupWindow*)win; w->vli.index = ALL_GROUP; - DoCommandP(CMD_DELETE_GROUP, STR_ERROR_GROUP_CAN_T_DELETE, (TileIndex)0, w->group_confirm, 0); + Command::Post(STR_ERROR_GROUP_CAN_T_DELETE, 0, w->group_confirm, 0, {}); } } @@ -772,7 +773,7 @@ public: } case WID_GL_CREATE_GROUP: { // Create a new group - DoCommandP(CMD_CREATE_GROUP, STR_ERROR_GROUP_CAN_T_CREATE, CcCreateGroup, 0, this->vli.vtype, this->vli.index); + Command::Post(STR_ERROR_GROUP_CAN_T_CREATE, CcCreateGroup, 0, this->vli.vtype, this->vli.index, {}); break; } @@ -801,14 +802,14 @@ public: case WID_GL_START_ALL: case WID_GL_STOP_ALL: { // Start/stop all vehicles of the list - DoCommandP(CMD_MASS_START_STOP, 0, (1 << 1) | (widget == WID_GL_START_ALL ? (1 << 0) : 0), this->vli.Pack()); + Command::Post(0, (1 << 1) | (widget == WID_GL_START_ALL ? (1 << 0) : 0), this->vli.Pack(), {}); break; } case WID_GL_REPLACE_PROTECTION: { const Group *g = Group::GetIfValid(this->vli.index); if (g != nullptr) { - DoCommandP(CMD_SET_GROUP_FLAG, 0, this->vli.index | (GroupFlags::GF_REPLACE_PROTECTION << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION) ? 0 : 1) | (_ctrl_pressed << 1)); + Command::Post(0, this->vli.index | (GroupFlags::GF_REPLACE_PROTECTION << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION) ? 0 : 1) | (_ctrl_pressed << 1), {}); } break; } @@ -823,7 +824,7 @@ public: case WID_GL_ALL_VEHICLES: // All vehicles case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles if (g->parent != INVALID_GROUP) { - DoCommandP(CMD_ALTER_GROUP, STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), INVALID_GROUP); + Command::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), INVALID_GROUP, {}); } this->group_sel = INVALID_GROUP; @@ -836,7 +837,7 @@ public: GroupID new_g = id_g >= this->groups.size() ? INVALID_GROUP : this->groups[id_g]->index; if (this->group_sel != new_g && g->parent != new_g) { - DoCommandP(CMD_ALTER_GROUP, STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), new_g); + Command::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), new_g, {}); } this->group_sel = INVALID_GROUP; @@ -851,7 +852,7 @@ public: { switch (widget) { case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles - DoCommandP(CMD_ADD_VEHICLE_GROUP, STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, 0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); + Command::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, 0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), {}); this->vehicle_sel = INVALID_VEHICLE; this->group_over = INVALID_GROUP; @@ -868,7 +869,7 @@ public: uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP); GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; - DoCommandP(CMD_ADD_VEHICLE_GROUP, STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0)); + Command::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), {}); break; } @@ -923,7 +924,7 @@ public: void OnQueryTextFinished(char *str) override { - if (str != nullptr) DoCommandP(CMD_ALTER_GROUP, STR_ERROR_GROUP_CAN_T_RENAME, 0, this->group_rename, 0, str); + if (str != nullptr) Command::Post(STR_ERROR_GROUP_CAN_T_RENAME, 0, this->group_rename, 0, str); this->group_rename = INVALID_GROUP; } @@ -953,19 +954,19 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: { // Send to Depots - DoCommandP(CMD_SEND_VEHICLE_TO_DEPOT, GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack()); + Command::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack(), {}); break; } case ADI_ADD_SHARED: // Add shared Vehicles assert(Group::IsValidID(this->vli.index)); - DoCommandP(CMD_ADD_SHARED_VEHICLE_GROUP, STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE, 0, this->vli.index, this->vli.vtype); + Command::Post(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE, 0, this->vli.index, this->vli.vtype, {}); break; case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group assert(Group::IsValidID(this->vli.index)); - DoCommandP(CMD_REMOVE_ALL_VEHICLES_GROUP, STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, (TileIndex)0, this->vli.index, 0); + Command::Post(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, 0, this->vli.index, 0, {}); break; default: NOT_REACHED(); } diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index 0dfaebc3b7..bf09b1b949 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -21,6 +21,7 @@ #include "strings_func.h" #include "hotkeys.h" #include "zoom_func.h" +#include "misc_cmd.h" #include "widgets/highscore_widget.h" @@ -96,7 +97,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { EndGameWindow(WindowDesc *desc) : EndGameHighScoreBaseWindow(desc) { /* Pause in single-player to have a look at the highscore at your own leisure */ - if (!_networking) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + if (!_networking) Command::Post(0, PM_PAUSED_NORMAL, 1, {}); this->background_img = SPR_TYCOON_IMG1_BEGIN; @@ -124,7 +125,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { void Close() override { - if (!_networking) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); // unpause + if (!_networking) Command::Post(0, PM_PAUSED_NORMAL, 0, {}); // unpause ShowHighscoreTable(this->window_number, this->rank); this->EndGameHighScoreBaseWindow::Close(); } @@ -159,7 +160,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { { /* pause game to show the chart */ this->game_paused_by_player = _pause_mode == PM_PAUSED_NORMAL; - if (!_networking && !this->game_paused_by_player) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + if (!_networking && !this->game_paused_by_player) Command::Post(0, PM_PAUSED_NORMAL, 1, {}); /* Close all always on-top windows to get a clean screen */ if (_game_mode != GM_MENU) HideVitalWindows(); @@ -174,7 +175,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { { if (_game_mode != GM_MENU) ShowVitalWindows(); - if (!_networking && !this->game_paused_by_player) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 0); // unpause + if (!_networking && !this->game_paused_by_player) Command::Post(0, PM_PAUSED_NORMAL, 0, {}); // unpause this->EndGameHighScoreBaseWindow::Close(); } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 5aea6f59a4..29da3c76ef 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -39,6 +39,7 @@ #include "widgets/industry_widget.h" #include "clear_map.h" #include "zoom_func.h" +#include "industry_cmd.h" #include "table/strings.h" @@ -679,7 +680,7 @@ public: case WID_DPI_FUND_WIDGET: { if (this->selected_type != INVALID_INDUSTRYTYPE) { if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && GetIndustrySpec(this->selected_type)->IsRawIndustry()) { - DoCommandP(CMD_BUILD_INDUSTRY, STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, 0, this->selected_type, InteractiveRandom()); + Command::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, 0, this->selected_type, InteractiveRandom(), {}); this->HandleButtonClick(WID_DPI_FUND_WIDGET); } else { HandlePlacePushButton(this, WID_DPI_FUND_WIDGET, SPR_CURSOR_INDUSTRY, HT_RECT); @@ -716,13 +717,13 @@ public: Backup old_generating_world(_generating_world, true, FILE_LINE); _ignore_restrictions = true; - DoCommandP(CMD_BUILD_INDUSTRY, STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, &CcBuildIndustry, tile, (layout_index << 8) | this->selected_type, seed); + Command::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, &CcBuildIndustry, tile, (layout_index << 8) | this->selected_type, seed, {}); cur_company.Restore(); old_generating_world.Restore(); _ignore_restrictions = false; } else { - success = DoCommandP(CMD_BUILD_INDUSTRY, STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, (layout_index << 8) | this->selected_type, seed); + success = Command::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, (layout_index << 8) | this->selected_type, seed, {}); } /* If an industry has been built, just reset the cursor and the system */ diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index c4fc2d5f9c..0a6b891502 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -16,6 +16,7 @@ #include "../framerate_type.h" #include "../command_func.h" #include "../network/network.h" +#include "../misc_cmd.h" #include "../safeguards.h" @@ -173,7 +174,7 @@ void StateGameLoop_LinkGraphPauseControl() if (_pause_mode & PM_PAUSED_LINK_GRAPH) { /* We are paused waiting on a job, check the job every tick. */ if (!LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_LINK_GRAPH, 0); + Command::Post(0, PM_PAUSED_LINK_GRAPH, 0, {}); } } else if (_pause_mode == PM_UNPAUSED && _date_fract == LinkGraphSchedule::SPAWN_JOIN_TICK - 2 && @@ -181,7 +182,7 @@ void StateGameLoop_LinkGraphPauseControl() LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { /* Perform check two _date_fract ticks before we would join, to make * sure it also works in multiplayer. */ - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_LINK_GRAPH, 1); + Command::Post(0, PM_PAUSED_LINK_GRAPH, 1, {}); } } diff --git a/src/main_gui.cpp b/src/main_gui.cpp index a4bec45d5c..847d328454 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -33,6 +33,7 @@ #include "guitimer_func.h" #include "error.h" #include "news_gui.h" +#include "misc_cmd.h" #include "saveload/saveload.h" @@ -326,7 +327,7 @@ struct MainWindow : Window case GHK_MONEY: // Gimme money /* You can only cheat for money in singleplayer mode. */ - if (!_networking) DoCommandP(CMD_MONEY_CHEAT, 0, 10000000, 0); + if (!_networking) Command::Post(0, 10000000, 0, {}); break; case GHK_UPDATE_COORDS: // Update the coordinates of all station signs diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index 243c5347aa..84c61e3f18 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -135,7 +135,7 @@ CommandCost CmdDecreaseLoan(DoCommandFlag flags, TileIndex tile, uint32 p1, uint static void AskUnsafeUnpauseCallback(Window *w, bool confirmed) { if (confirmed) { - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_ERROR, 0); + Command::Post(0, PM_PAUSED_ERROR, 0, {}); } } diff --git a/src/network/network.cpp b/src/network/network.cpp index 8194f34d07..3bd287f85a 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -395,7 +395,7 @@ static void CheckPauseHelper(bool pause, PauseMode pm) { if (pause == ((_pause_mode & pm) != PM_UNPAUSED)) return; - DoCommandP(CMD_PAUSE, 0, pm, pause ? 1 : 0); + Command::Post(0, pm, pause ? 1 : 0, {}); } /** diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 472d5e60e2..983f4b5659 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -451,5 +451,5 @@ template void UnpackNetworkCommand(const CommandPacket *cp) { auto args = EndianBufferReader::ToValue::Args>(cp->data); - std::apply(&InjectNetworkCommand, std::tuple_cat(std::make_tuple(Tcmd, cp->err_msg, cp->callback, cp->my_cmd), args)); + Command::PostFromNet(cp->err_msg, cp->callback, cp->my_cmd, cp->tile, args); } diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 82e01e81e2..a2b34593eb 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -36,6 +36,7 @@ #include "../zoom_func.h" #include "../sprite.h" #include "../settings_internal.h" +#include "../company_cmd.h" #include "../widgets/network_widget.h" @@ -1395,7 +1396,7 @@ static void AdminCompanyResetCallback(Window *w, bool confirmed) { if (confirmed) { if (NetworkCompanyHasClients(_admin_company_id)) return; - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | _admin_company_id << 16 | CRR_MANUAL << 24, 0); + Command::Post(0, CCA_DELETE | _admin_company_id << 16 | CRR_MANUAL << 24, 0, {}); } } @@ -1535,7 +1536,7 @@ private: static void OnClickCompanyNew(NetworkClientListWindow *w, Point pt, CompanyID company_id) { if (_network_server) { - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW, _network_own_client_id); + Command::Post(0, CCA_NEW, _network_own_client_id, {}); } else { NetworkSendCommand(CMD_COMPANY_CTRL, STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 967ad40a89..65f3188de8 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -29,6 +29,7 @@ #include "../order_backup.h" #include "../core/pool_func.hpp" #include "../core/random_func.hpp" +#include "../company_cmd.h" #include "../rev.h" #include #include @@ -1555,7 +1556,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_unprotected-months, and is there no protection? */ if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) { /* Shut the company down */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0); + Command::Post(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, {}); IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no password.", c->index + 1); } /* Is the company empty for autoclean_protected-months, and there is a protection? */ @@ -1569,7 +1570,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_novehicles-months, and has no vehicles? */ if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) { /* Shut the company down */ - DoCommandP(CMD_COMPANY_CTRL, 0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0); + Command::Post(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, {}); IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no vehicles.", c->index + 1); } } else { diff --git a/src/object_gui.cpp b/src/object_gui.cpp index a3ea3f8b17..562af15ae8 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -25,6 +25,7 @@ #include "window_func.h" #include "zoom_func.h" #include "terraform_cmd.h" +#include "object_cmd.h" #include "widgets/object_widget.h" @@ -542,8 +543,8 @@ public: void OnPlaceObject(Point pt, TileIndex tile) override { ObjectClass *objclass = ObjectClass::Get(_selected_object_class); - DoCommandP(CMD_BUILD_OBJECT, STR_ERROR_CAN_T_BUILD_OBJECT, CcTerraform, - tile, objclass->GetSpec(_selected_object_index)->Index(), _selected_object_view); + Command::Post(STR_ERROR_CAN_T_BUILD_OBJECT, CcTerraform, + tile, objclass->GetSpec(_selected_object_index)->Index(), _selected_object_view, {}); } void OnPlaceObjectAbort() override diff --git a/src/openttd.cpp b/src/openttd.cpp index abd5d99df6..c5c849e71c 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -66,6 +66,7 @@ #include "framerate_type.h" #include "industry.h" #include "network/network_gui.h" +#include "misc_cmd.h" #include "linkgraph/linkgraphschedule.h" @@ -851,7 +852,7 @@ static void MakeNewGameDone() /* In a dedicated server, the server does not play */ if (!VideoDriver::GetInstance()->HasGUI()) { OnStartGame(true); - if (_settings_client.gui.pause_on_newgame) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + if (_settings_client.gui.pause_on_newgame) Command::Post(0, PM_PAUSED_NORMAL, 1, {}); return; } @@ -880,7 +881,7 @@ static void MakeNewGameDone() NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass); } - if (_settings_client.gui.pause_on_newgame) DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, 1); + if (_settings_client.gui.pause_on_newgame) Command::Post(0, PM_PAUSED_NORMAL, 1, {}); CheckEngines(); CheckIndustries(); @@ -1045,7 +1046,7 @@ void SwitchToMode(SwitchMode new_mode) } OnStartGame(_network_dedicated); /* Decrease pause counter (was increased from opening load dialog) */ - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 0); + Command::Post(0, PM_PAUSED_SAVELOAD, 0, {}); } break; } @@ -1067,7 +1068,7 @@ void SwitchToMode(SwitchMode new_mode) SetLocalCompany(OWNER_NONE); _settings_newgame.game_creation.starting_year = _cur_year; /* Cancel the saveload pausing */ - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_SAVELOAD, 0); + Command::Post(0, PM_PAUSED_SAVELOAD, 0, {}); } else { SetDParamStr(0, GetSaveLoadErrorString()); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 80fc9fa6d1..987b3154f2 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -171,7 +171,7 @@ CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, uint32 p1, /* If it's not a backup of us, ignore it. */ if (ob->user != user) continue; - DoCommandP(CMD_CLEAR_ORDER_BACKUP, 0, 0, user); + Command::Post(0, 0, user, {}); return; } } diff --git a/src/order_gui.cpp b/src/order_gui.cpp index b934b9d161..50413c7352 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -29,6 +29,7 @@ #include "aircraft.h" #include "engine_func.h" #include "vehicle_func.h" +#include "order_cmd.h" #include "widgets/order_widget.h" @@ -591,7 +592,7 @@ private: } if (order->GetLoadType() == load_type) return; // If we still match, do nothing - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (load_type << 4)); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (load_type << 4), {}); } /** @@ -606,7 +607,7 @@ private: if (order == nullptr) return; i = (order->GetDepotOrderType() & ODTFB_SERVICE) ? DA_ALWAYS_GO : DA_SERVICE; } - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4)); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4), {}); } /** @@ -621,7 +622,7 @@ private: _settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); order.SetDepotActionType(ODATFB_NEAREST_DEPOT); - DoCommandP(CMD_INSERT_ORDER, STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); + Command::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), {}); } /** @@ -641,11 +642,11 @@ private: } if (order->GetUnloadType() == unload_type) return; // If we still match, do nothing - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4)); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4), {}); /* Transfer and unload orders with leave empty as default */ if (unload_type == OUFB_TRANSFER || unload_type == OUFB_UNLOAD) { - DoCommandP(CMD_MODIFY_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (OLFB_NO_LOAD << 4)); + Command::Post(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (OLFB_NO_LOAD << 4), {}); this->SetWidgetDirty(WID_O_FULL_LOAD); } } @@ -669,7 +670,7 @@ private: } this->SetWidgetDirty(WID_O_NON_STOP); - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_NON_STOP | non_stop << 4); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_NON_STOP | non_stop << 4, {}); } /** @@ -682,8 +683,8 @@ private: if (_ctrl_pressed && this->vehicle->cur_implicit_order_index == this->OrderGetSel()) return; if (this->vehicle->GetNumOrders() <= 1) return; - DoCommandP(CMD_SKIP_TO_ORDER, _ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER, - this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders())); + Command::Post(_ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER, + this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders()), {}); } /** @@ -694,7 +695,7 @@ private: /* When networking, move one order lower */ int selected = this->selected_order + (int)_networking; - if (DoCommandP(CMD_DELETE_ORDER, STR_ERROR_CAN_T_DELETE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel())) { + if (Command::Post(STR_ERROR_CAN_T_DELETE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), {})) { this->selected_order = selected >= this->vehicle->GetNumOrders() ? -1 : selected; this->UpdateButtonState(); } @@ -719,7 +720,7 @@ private: /* Get another vehicle that share orders with this vehicle. */ Vehicle *other_shared = (this->vehicle->FirstShared() == this->vehicle) ? this->vehicle->NextShared() : this->vehicle->PreviousShared(); /* Copy the order list of the other vehicle. */ - if (DoCommandP(CMD_CLONE_ORDER, STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST, this->vehicle->tile, this->vehicle->index | CO_COPY << 30, other_shared->index)) { + if (Command::Post(STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST, this->vehicle->tile, this->vehicle->index | CO_COPY << 30, other_shared->index, {})) { this->UpdateButtonState(); } } @@ -734,10 +735,10 @@ private: { if (_ctrl_pressed) { /* Cancel refitting */ - DoCommandP(CMD_ORDER_REFIT, this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT); + Command::Post(this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT, {}); } else { if (i == 1) { // Auto-refit to available cargo type. - DoCommandP(CMD_ORDER_REFIT, this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | CT_AUTO_REFIT); + Command::Post(this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | CT_AUTO_REFIT, {}); } else { ShowVehicleRefitWindow(this->vehicle, this->OrderGetSel(), this, auto_refit); } @@ -1159,7 +1160,7 @@ public: order.index = 0; order.MakeConditional(order_id); - DoCommandP(CMD_INSERT_ORDER, STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack()); + Command::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), {}); } ResetObjectToPlace(); break; @@ -1182,9 +1183,9 @@ public: this->selected_order = -1; } else if (sel == this->selected_order) { if (this->vehicle->type == VEH_TRAIN && sel < this->vehicle->GetNumOrders()) { - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel << 20), - MOF_STOP_LOCATION | ((this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END) << 4); + MOF_STOP_LOCATION | ((this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END) << 4, {}); } } else { /* Select clicked order */ @@ -1331,7 +1332,7 @@ public: default: break; } - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4, {}); } } @@ -1369,11 +1370,11 @@ public: break; case WID_O_COND_VARIABLE: - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VARIABLE | index << 4); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VARIABLE | index << 4, {}); break; case WID_O_COND_COMPARATOR: - DoCommandP(CMD_MODIFY_ORDER, STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_COMPARATOR | index << 4); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_COMPARATOR | index << 4, {}); break; } } @@ -1386,7 +1387,7 @@ public: VehicleOrderID to_order = this->GetOrderFromPt(pt.y); if (!(from_order == to_order || from_order == INVALID_VEH_ORDER_ID || from_order > this->vehicle->GetNumOrders() || to_order == INVALID_VEH_ORDER_ID || to_order > this->vehicle->GetNumOrders()) && - DoCommandP(CMD_MOVE_ORDER, STR_ERROR_CAN_T_MOVE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16))) { + Command::Post(STR_ERROR_CAN_T_MOVE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16), {})) { this->selected_order = -1; this->UpdateButtonState(); } @@ -1438,7 +1439,7 @@ public: const Order cmd = GetOrderCmdFromTile(this->vehicle, tile); if (cmd.IsType(OT_NOTHING)) return; - if (DoCommandP(CMD_INSERT_ORDER, STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack())) { + if (Command::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack(), {})) { /* With quick goto the Go To button stays active */ if (!_settings_client.gui.quick_goto) ResetObjectToPlace(); } @@ -1455,8 +1456,8 @@ public: bool share_order = _ctrl_pressed || this->goto_type == OPOS_SHARE; if (this->vehicle->GetNumOrders() != 0 && !share_order) return false; - if (DoCommandP(CMD_CLONE_ORDER, share_order ? STR_ERROR_CAN_T_SHARE_ORDER_LIST : STR_ERROR_CAN_T_COPY_ORDER_LIST, - this->vehicle->tile, this->vehicle->index | (share_order ? CO_SHARE : CO_COPY) << 30, v->index)) { + if (Command::Post(share_order ? STR_ERROR_CAN_T_SHARE_ORDER_LIST : STR_ERROR_CAN_T_COPY_ORDER_LIST, + this->vehicle->tile, this->vehicle->index | (share_order ? CO_SHARE : CO_COPY) << 30, v->index, {})) { this->selected_order = -1; ResetObjectToPlace(); } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index f88352f9e6..a57e2f8e53 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -39,6 +39,7 @@ #include "station_cmd.h" #include "tunnelbridge_cmd.h" #include "waypoint_cmd.h" +#include "rail_cmd.h" #include "station_map.h" #include "tunnelbridge_map.h" @@ -95,10 +96,13 @@ void CcPlaySound_CONSTRUCTION_RAIL(const CommandCost &result, Commands cmd, Tile static void GenericPlaceRail(TileIndex tile, int cmd) { - DoCommandP(_remove_button_clicked ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL, - _remove_button_clicked ? STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK : STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, - CcPlaySound_CONSTRUCTION_RAIL, - tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3)); + if (_remove_button_clicked) { + Command::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, + tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3), {}); + } else { + Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, + tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3), {}); + } } /** @@ -114,7 +118,7 @@ static void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track) if (GetRailTileType(tile) == RAIL_TILE_SIGNALS && !_settings_client.gui.auto_remove_signals) return; if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) return; - DoCommandP(CMD_BUILD_SINGLE_RAIL, tile, _cur_railtype, track | (_settings_client.gui.auto_remove_signals << 3)); + Command::Post(tile, _cur_railtype, track | (_settings_client.gui.auto_remove_signals << 3), {}); } /** Additional pieces of track to add at the entrance of a depot. */ @@ -168,7 +172,7 @@ static void PlaceRail_Waypoint(TileIndex tile) } else { /* Tile where we can't build rail waypoints. This is always going to fail, * but provides the user with a proper error message. */ - DoCommandP(CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16); + Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, {}); } } @@ -208,7 +212,7 @@ static void PlaceRail_Station(TileIndex tile) uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, tile, p1, p2_final); + return Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, tile, p1, p2_final, {}); } }; @@ -236,7 +240,7 @@ static void GenericPlaceSignals(TileIndex tile) Track track = FindFirstTrack(trackbits); if (_remove_button_clicked) { - DoCommandP(CMD_REMOVE_SIGNALS, STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, tile, track, 0); + Command::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, tile, track, 0, {}); } else { const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0); @@ -267,8 +271,8 @@ static void GenericPlaceSignals(TileIndex tile) SB(p1, 9, 6, cycle_types); } - DoCommandP(CMD_BUILD_SIGNALS, (w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, - CcPlaySound_CONSTRUCTION_RAIL, tile, p1, 0); + Command::Post((w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, + CcPlaySound_CONSTRUCTION_RAIL, tile, p1, 0, {}); } } @@ -370,10 +374,13 @@ static void BuildRailClick_Remove(Window *w) static void DoRailroadTrack(int mode) { uint32 p2 = _cur_railtype | (mode << 6) | (_settings_client.gui.auto_remove_signals << 11); - DoCommandP(_remove_button_clicked ? CMD_REMOVE_RAILROAD_TRACK : CMD_BUILD_RAILROAD_TRACK, - _remove_button_clicked ? STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK : STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, - CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2); + if (_remove_button_clicked) { + Command::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + } else { + Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + } } static void HandleAutodirPlacement() @@ -424,10 +431,13 @@ static void HandleAutoSignalPlacement() /* _settings_client.gui.drag_signals_density is given as a parameter such that each user * in a network game can specify their own signal density */ - DoCommandP(_remove_button_clicked ? CMD_REMOVE_SIGNAL_TRACK : CMD_BUILD_SIGNAL_TRACK, - _remove_button_clicked ? STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, - CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2); + if (_remove_button_clicked) { + Command::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + } else { + Command::Post(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL, + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + } } @@ -653,8 +663,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_DEPOT: - DoCommandP(CMD_BUILD_TRAIN_DEPOT, STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, - CcRailDepot, tile, _cur_railtype, _build_depot_direction); + Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, CcRailDepot, tile, _cur_railtype, _build_depot_direction, {}); break; case WID_RAT_BUILD_WAYPOINT: @@ -674,7 +683,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_TUNNEL: - DoCommandP(CMD_BUILD_TUNNEL, STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0); + Command::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, {}); break; case WID_RAT_CONVERT_RAIL: @@ -716,7 +725,7 @@ struct BuildRailToolbarWindow : Window { break; case DDSP_CONVERT_RAIL: - DoCommandP(CMD_CONVERT_RAIL, STR_ERROR_CAN_T_CONVERT_RAIL, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0)); + Command::Post(STR_ERROR_CAN_T_CONVERT_RAIL, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0), {}); break; case DDSP_REMOVE_STATION: @@ -724,14 +733,14 @@ struct BuildRailToolbarWindow : Window { if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) { /* Station */ if (_remove_button_clicked) { - DoCommandP(CMD_REMOVE_FROM_RAIL_STATION, STR_ERROR_CAN_T_REMOVE_PART_OF_STATION, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); + Command::Post(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1, {}); } else { HandleStationPlacement(start_tile, end_tile); } } else { /* Waypoint */ if (_remove_button_clicked) { - DoCommandP(CMD_REMOVE_FROM_RAIL_WAYPOINT, STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1); + Command::Post(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1, {}); } else { TileArea ta(start_tile, end_tile); uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 6 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24; @@ -744,7 +753,7 @@ struct BuildRailToolbarWindow : Window { uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, ta.tile, p1, p2_final); + return Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, ta.tile, p1, p2_final, {}); } }; @@ -913,7 +922,7 @@ static void HandleStationPlacement(TileIndex start, TileIndex end) uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, ta.tile, p1, p2_final); + return Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, ta.tile, p1, p2_final, {}); } }; diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 145934ffc5..948095f773 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -32,6 +32,7 @@ #include "core/geometry_func.hpp" #include "date_func.h" #include "station_cmd.h" +#include "road_cmd.h" #include "tunnelbridge_cmd.h" #include "widgets/road_widget.h" @@ -127,7 +128,7 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) /* if there is a roadpiece just outside of the station entrance, build a connecting route */ if (IsNormalRoadTile(tile)) { if (GetRoadBits(tile, GetRoadTramType(_cur_roadtype)) != ROAD_NONE) { - DoCommandP(CMD_BUILD_ROAD, tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0); + Command::Post(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, {}); } } } @@ -205,7 +206,7 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, S uint32 p2_final = p2; if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - return DoCommandP(CMD_BUILD_ROAD_STOP, err_msg, CcRoadStop, ta.tile, p1, p2_final); + return Command::Post(err_msg, CcRoadStop, ta.tile, p1, p2_final, {}); } }; @@ -566,8 +567,8 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_DEPOT: - DoCommandP(CMD_BUILD_ROAD_DEPOT, this->rti->strings.err_depot, CcRoadDepot, - tile, _cur_roadtype << 2 | _road_depot_orientation, 0); + Command::Post(this->rti->strings.err_depot, CcRoadDepot, + tile, _cur_roadtype << 2 | _road_depot_orientation, 0, {}); break; case WID_ROT_BUS_STATION: @@ -583,8 +584,8 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_BUILD_TUNNEL: - DoCommandP(CMD_BUILD_TUNNEL, STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRoadTunnel, - tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0); + Command::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRoadTunnel, + tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, {}); break; case WID_ROT_CONVERT_ROAD: @@ -685,9 +686,13 @@ struct BuildRoadToolbarWindow : Window { * flags */ _place_road_flag = (RoadFlags)((_place_road_flag & RF_DIR_Y) ? (_place_road_flag & 0x07) : (_place_road_flag >> 3)); - DoCommandP(_remove_button_clicked ? CMD_REMOVE_LONG_ROAD : CMD_BUILD_LONG_ROAD, - _remove_button_clicked ? this->rti->strings.err_remove_road : this->rti->strings.err_build_road, CcPlaySound_CONSTRUCTION_OTHER, - start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10)); + if (_remove_button_clicked) { + Command::Post(this->rti->strings.err_remove_road, CcPlaySound_CONSTRUCTION_OTHER, + start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10), {}); + } else { + Command::Post(this->rti->strings.err_build_road, CcPlaySound_CONSTRUCTION_OTHER, + start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10), {}); + } break; case DDSP_BUILD_BUSSTOP: @@ -695,7 +700,7 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_BUS_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS); + Command::Post(this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS, {}); } else { PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, this->rti->strings.err_build_station[ROADSTOP_BUS]); } @@ -707,7 +712,7 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK); + Command::Post(this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, {}); } else { PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, this->rti->strings.err_build_station[ROADSTOP_TRUCK]); } @@ -715,7 +720,7 @@ struct BuildRoadToolbarWindow : Window { break; case DDSP_CONVERT_ROAD: - DoCommandP(CMD_CONVERT_ROAD, rti->strings.err_convert_road, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype); + Command::Post(rti->strings.err_convert_road, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype, {}); break; } } diff --git a/src/settings.cpp b/src/settings.cpp index 1bf6513044..63c7478a04 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1550,7 +1550,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) const IntSettingDesc *setting = sd->AsIntSetting(); if ((setting->flags & SF_PER_COMPANY) != 0) { if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) { - return DoCommandP(CMD_CHANGE_COMPANY_SETTING, 0, 0, value, setting->GetName()); + return Command::Post(0, 0, value, setting->GetName()); } setting->ChangeValue(&_settings_client.company, value); @@ -1576,7 +1576,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) /* send non-company-based settings over the network */ if (!_networking || (_networking && _network_server)) { - return DoCommandP(CMD_CHANGE_SETTING, 0, 0, value, setting->GetName()); + return Command::Post(0, 0, value, setting->GetName()); } return false; } diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index cf742df835..4fdfc0ab5f 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -132,5 +132,5 @@ void CcPlaceSign(const CommandCost &result, Commands cmd, TileIndex tile, uint32 */ void PlaceProc_Sign(TileIndex tile) { - DoCommandP(CMD_PLACE_SIGN, STR_ERROR_CAN_T_PLACE_SIGN_HERE, CcPlaceSign, tile, 0, 0); + Command::Post(STR_ERROR_CAN_T_PLACE_SIGN_HERE, CcPlaceSign, tile, 0, 0, {}); } diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 0bb9fa2daf..b10e6d38c5 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -26,6 +26,7 @@ #include "hotkeys.h" #include "transparency.h" #include "gui.h" +#include "signs_cmd.h" #include "widgets/sign_widget.h" @@ -413,7 +414,7 @@ Window *ShowSignList() static bool RenameSign(SignID index, const char *text) { bool remove = StrEmpty(text); - DoCommandP(CMD_RENAME_SIGN, StrEmpty(text) ? STR_ERROR_CAN_T_DELETE_SIGN : STR_ERROR_CAN_T_CHANGE_SIGN_NAME, 0, index, 0, text); + Command::Post(StrEmpty(text) ? STR_ERROR_CAN_T_DELETE_SIGN : STR_ERROR_CAN_T_CHANGE_SIGN_NAME, 0, index, 0, text); return remove; } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 2e04e7ac44..1177e558c1 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -31,6 +31,7 @@ #include "town.h" #include "linkgraph/linkgraph.h" #include "zoom_func.h" +#include "station_cmd.h" #include "widgets/station_widget.h" @@ -1947,7 +1948,7 @@ struct StationViewWindow : public Window { break; case WID_SV_CLOSE_AIRPORT: - DoCommandP(CMD_OPEN_CLOSE_AIRPORT, 0, this->window_number, 0); + Command::Post(0, this->window_number, 0, {}); break; case WID_SV_TRAINS: // Show list of scheduled trains to this station @@ -2084,7 +2085,7 @@ struct StationViewWindow : public Window { { if (str == nullptr) return; - DoCommandP(CMD_RENAME_STATION, STR_ERROR_CAN_T_RENAME_STATION, 0, this->window_number, 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_STATION, 0, this->window_number, 0, str); } void OnResize() override diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 5330b8a304..21dba8fd1a 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -25,6 +25,7 @@ #include "company_base.h" #include "tilehighlight_func.h" #include "vehicle_base.h" +#include "story_cmd.h" #include "widgets/story_widget.h" @@ -566,7 +567,7 @@ protected: this->SetTimeout(); this->SetWidgetDirty(WID_SB_PAGE_PANEL); - DoCommandP(CMD_STORY_PAGE_BUTTON, 0, pe.index, 0); + Command::Post(0, pe.index, 0, {}); break; case SPET_BUTTON_TILE: @@ -921,7 +922,7 @@ public: return; } - DoCommandP(CMD_STORY_PAGE_BUTTON, tile, pe->index, 0); + Command::Post(tile, pe->index, 0, {}); ResetObjectToPlace(); } @@ -940,7 +941,7 @@ public: VehicleType wanted_vehtype = data.GetVehicleType(); if (wanted_vehtype != VEH_INVALID && wanted_vehtype != v->type) return false; - DoCommandP(CMD_STORY_PAGE_BUTTON, 0, pe->index, v->index); + Command::Post(0, pe->index, v->index, {}); ResetObjectToPlace(); return true; } diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 71d897c3d9..c65adad7d1 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -35,6 +35,8 @@ #include "zoom_func.h" #include "rail_cmd.h" #include "landscape_cmd.h" +#include "terraform_cmd.h" +#include "object_cmd.h" #include "widgets/terraform_widget.h" @@ -63,7 +65,7 @@ static void GenerateDesertArea(TileIndex end, TileIndex start) TileArea ta(start, end); for (TileIndex tile : ta) { SetTropicZone(tile, (_ctrl_pressed) ? TROPICZONE_NORMAL : TROPICZONE_DESERT); - DoCommandP(CMD_LANDSCAPE_CLEAR, tile, 0, 0); + Command::Post(tile, 0, 0, {}); MarkTileDirtyByTile(tile); } old_generating_world.Restore(); @@ -118,16 +120,16 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t switch (proc) { case DDSP_DEMOLISH_AREA: - DoCommandP(CMD_CLEAR_AREA, STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed ? 1 : 0); + Command::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed ? 1 : 0, {}); break; case DDSP_RAISE_AND_LEVEL_AREA: - DoCommandP(CMD_LEVEL_LAND, STR_ERROR_CAN_T_RAISE_LAND_HERE, CcTerraform, end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0)); + Command::Post(STR_ERROR_CAN_T_RAISE_LAND_HERE, CcTerraform, end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0), {}); break; case DDSP_LOWER_AND_LEVEL_AREA: - DoCommandP(CMD_LEVEL_LAND, STR_ERROR_CAN_T_LOWER_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0)); + Command::Post(STR_ERROR_CAN_T_LOWER_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0), {}); break; case DDSP_LEVEL_AREA: - DoCommandP(CMD_LEVEL_LAND, STR_ERROR_CAN_T_LEVEL_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0)); + Command::Post(STR_ERROR_CAN_T_LEVEL_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0), {}); break; case DDSP_CREATE_ROCKS: GenerateRockyArea(end_tile, start_tile); @@ -241,7 +243,7 @@ struct TerraformToolbarWindow : Window { break; case WID_TT_BUY_LAND: // Buy land button - DoCommandP(CMD_BUILD_OBJECT, STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0); + Command::Post(STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0, {}); break; case WID_TT_PLACE_SIGN: // Place sign button @@ -398,7 +400,7 @@ static void CommonRaiseLowerBigLand(TileIndex tile, int mode) StringID msg = mode ? STR_ERROR_CAN_T_RAISE_LAND_HERE : STR_ERROR_CAN_T_LOWER_LAND_HERE; - DoCommandP(CMD_TERRAFORM_LAND, msg, CcTerraform, tile, SLOPE_N, (uint32)mode); + Command::Post(msg, CcTerraform, tile, SLOPE_N, (uint32)mode, {}); } else { assert(_terraform_size != 0); TileArea ta(tile, _terraform_size, _terraform_size); @@ -425,7 +427,7 @@ static void CommonRaiseLowerBigLand(TileIndex tile, int mode) for (TileIndex tile2 : ta) { if (TileHeight(tile2) == h) { - DoCommandP(CMD_TERRAFORM_LAND, tile2, SLOPE_N, (uint32)mode); + Command::Post(tile2, SLOPE_N, (uint32)mode, {}); } } } diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index a205a505e8..12c3914875 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -22,6 +22,7 @@ #include "date_gui.h" #include "vehicle_gui.h" #include "settings_type.h" +#include "timetable_cmd.h" #include "widgets/timetable_widget.h" @@ -142,7 +143,7 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID */ static void ChangeTimetableStartCallback(const Window *w, Date date) { - DoCommandP(CMD_SET_TIMETABLE_START, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, w->window_number, date); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, w->window_number, date, {}); } @@ -578,25 +579,25 @@ struct TimetableWindow : Window { case WID_VT_CLEAR_TIME: { // Clear waiting time. uint32 p1 = PackTimetableArgs(v, this->sel_index, false); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, p1, 0); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, 0, {}); break; } case WID_VT_CLEAR_SPEED: { // Clear max speed button. uint32 p1 = PackTimetableArgs(v, this->sel_index, true); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, p1, UINT16_MAX); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, UINT16_MAX, {}); break; } case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter. - DoCommandP(CMD_SET_VEHICLE_ON_TIME, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, v->index, 0); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, 0, {}); break; case WID_VT_AUTOFILL: { // Autofill the timetable. uint32 p2 = 0; if (!HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(p2, 0); if (_ctrl_pressed) SetBit(p2, 1); - DoCommandP(CMD_AUTOFILL_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (TileIndex)0, v->index, p2); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, p2, {}); break; } @@ -629,7 +630,7 @@ struct TimetableWindow : Window { uint32 p2 = std::min(val, UINT16_MAX); - DoCommandP(CMD_CHANGE_TIMETABLE, STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, p2); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, p2, {}); } void OnResize() override diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 665556e8ab..b2b25afa6c 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -49,6 +49,7 @@ #include "framerate_type.h" #include "guitimer_func.h" #include "screenshot_gui.h" +#include "misc_cmd.h" #include "widgets/toolbar_widget.h" @@ -265,7 +266,7 @@ static CallBackFunction ToolbarPauseClick(Window *w) { if (_networking && !_network_server) return CBF_NONE; // only server can pause the game - if (DoCommandP(CMD_PAUSE, 0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED)) { + if (Command::Post(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, {})) { if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); } return CBF_NONE; diff --git a/src/town_gui.cpp b/src/town_gui.cpp index cb88c5c005..8f315a0557 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -33,6 +33,7 @@ #include "stringfilter_type.h" #include "widgets/dropdown_func.h" #include "town_kdtree.h" +#include "town_cmd.h" #include "widgets/town_widget.h" @@ -287,7 +288,7 @@ public: } case WID_TA_EXECUTE: - DoCommandP(CMD_DO_TOWN_ACTION, STR_ERROR_CAN_T_DO_THIS, this->town->xy, this->window_number, this->sel_index); + Command::Post(STR_ERROR_CAN_T_DO_THIS, this->town->xy, this->window_number, this->sel_index, {}); break; } } @@ -474,12 +475,12 @@ public: _warn_town_no_roads = true; } - DoCommandP(CMD_EXPAND_TOWN, STR_ERROR_CAN_T_EXPAND_TOWN, (TileIndex)0, this->window_number, 0); + Command::Post(STR_ERROR_CAN_T_EXPAND_TOWN, 0, this->window_number, 0, {}); break; } case WID_TV_DELETE: // delete town - only available on Scenario editor - DoCommandP(CMD_DELETE_TOWN, STR_ERROR_TOWN_CAN_T_DELETE, (TileIndex)0, this->window_number, 0); + Command::Post(STR_ERROR_TOWN_CAN_T_DELETE, 0, this->window_number, 0, {}); break; } } @@ -561,7 +562,7 @@ public: { if (str == nullptr) return; - DoCommandP(CMD_RENAME_TOWN, STR_ERROR_CAN_T_RENAME_TOWN, 0, this->window_number, 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_TOWN, 0, this->window_number, 0, str); } }; @@ -1162,7 +1163,7 @@ public: if (strcmp(buf, this->townname_editbox.text.buf) != 0) name = this->townname_editbox.text.buf; } - bool success = DoCommandP(CMD_FOUND_TOWN, errstr, cc, + bool success = Command::Post(errstr, cc, tile, this->town_size | this->city << 2 | this->town_layout << 3 | random << 6, townnameparts, name); /* Rerandomise name, if success and no cost-estimation. */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index b060ecdbad..a86e835bd3 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -35,6 +35,7 @@ #include "newgrf_debug.h" #include "framerate_type.h" #include "train_cmd.h" +#include "misc_cmd.h" #include "table/strings.h" #include "table/train_sprites.h" @@ -87,7 +88,7 @@ void CheckTrainsLengths() if (!_networking && first) { first = false; - DoCommandP(CMD_PAUSE, 0, PM_PAUSED_ERROR, 1); + Command::Post(0, PM_PAUSED_ERROR, 1, {}); } /* Break so we warn only once for each train. */ break; diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 7031a89684..8fc97d8571 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -14,6 +14,7 @@ #include "strings_func.h" #include "vehicle_func.h" #include "zoom_func.h" +#include "train_cmd.h" #include "table/strings.h" @@ -45,7 +46,7 @@ void CcBuildWagon(const CommandCost &result, Commands cmd, TileIndex tile, uint3 if (found != nullptr) { found = found->Last(); /* put the new wagon at the end of the loco. */ - DoCommandP(CMD_MOVE_RAIL_VEHICLE, 0, _new_vehicle_id, found->index); + Command::Post(0, _new_vehicle_id, found->index, {}); InvalidateWindowClassesData(WC_TRAINS_LIST, 0); } } diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index f176668b1a..794135716b 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -19,6 +19,7 @@ #include "strings_func.h" #include "zoom_func.h" #include "tree_map.h" +#include "tree_cmd.h" #include "widgets/tree_widget.h" @@ -230,7 +231,7 @@ public: TileIndex tile = TileVirtXY(pt.x, pt.y); if (this->mode == PM_NORMAL) { - DoCommandP(CMD_PLANT_TREE, tile, this->tree_to_plant, tile); + Command::Post(tile, this->tree_to_plant, tile, {}); } else { this->DoPlantForest(tile); } @@ -240,7 +241,7 @@ public: void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL && pt.x != -1 && select_proc == DDSP_PLANT_TREES) { - DoCommandP(CMD_PLANT_TREE, STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, this->tree_to_plant, start_tile); + Command::Post(STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, this->tree_to_plant, start_tile, {}); } } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index d5d6978cc5..c549101504 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -38,6 +38,9 @@ #include "zoom_func.h" #include "depot_cmd.h" #include "vehicle_cmd.h" +#include "order_cmd.h" +#include "roadveh_cmd.h" +#include "train_cmd.h" #include "safeguards.h" @@ -1035,9 +1038,9 @@ struct RefitWindow : public Window { if (this->order == INVALID_VEH_ORDER_ID) { bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX; - if (DoCommandP(CMD_REFIT_VEHICLE, GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16) && delete_window) this->Close(); + if (Command::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16, {}) && delete_window) this->Close(); } else { - if (DoCommandP(CMD_ORDER_REFIT, v->tile, v->index, this->cargo->cargo | this->order << 16)) this->Close(); + if (Command::Post(v->tile, v->index, this->cargo->cargo | this->order << 16, {})) this->Close(); } } break; @@ -1896,7 +1899,7 @@ public: case WID_VL_STOP_ALL: case WID_VL_START_ALL: - DoCommandP(CMD_MASS_START_STOP, 0, (1 << 1) | (widget == WID_VL_START_ALL ? (1 << 0) : 0), this->window_number); + Command::Post(0, (1 << 1) | (widget == WID_VL_START_ALL ? (1 << 0) : 0), this->window_number, {}); break; } } @@ -1921,7 +1924,7 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: // Send to Depots - DoCommandP(CMD_SEND_VEHICLE_TO_DEPOT, GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number); + Command::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number, {}); break; default: NOT_REACHED(); @@ -2424,7 +2427,7 @@ struct VehicleDetailsWindow : Window { mod = GetServiceIntervalClamped(mod + v->GetServiceInterval(), v->ServiceIntervalIsPercent()); if (mod == v->GetServiceInterval()) return; - DoCommandP(CMD_CHANGE_SERVICE_INT, STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17)); + Command::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17), {}); break; } @@ -2460,7 +2463,7 @@ struct VehicleDetailsWindow : Window { bool iscustom = index != 0; bool ispercent = iscustom ? (index == 2) : Company::Get(v->owner)->settings.vehicle.servint_ispercent; uint16 interval = GetServiceIntervalClamped(v->GetServiceInterval(), ispercent); - DoCommandP(CMD_CHANGE_SERVICE_INT, STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17)); + Command::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17), {}); break; } } @@ -2643,7 +2646,7 @@ void CcStartStopVehicle(const CommandCost &result, Commands cmd, TileIndex tile, void StartStopVehicle(const Vehicle *v, bool texteffect) { assert(v->IsPrimaryVehicle()); - DoCommandP(CMD_START_STOP_VEHICLE, _vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, 0); + Command::Post(_vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, 0, {}); } /** Checks whether the vehicle may be refitted at the moment.*/ @@ -2967,7 +2970,7 @@ public: break; case WID_VV_GOTO_DEPOT: // goto hangar - DoCommandP(CMD_SEND_VEHICLE_TO_DEPOT, GetCmdSendToDepotMsg(v), v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0); + Command::Post(GetCmdSendToDepotMsg(v), v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0, {}); break; case WID_VV_REFIT: // refit ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID, this); @@ -2991,21 +2994,21 @@ public: * There is no point to it except for starting the vehicle. * For starting the vehicle the player has to open the depot GUI, which is * most likely already open, but is also visible in the vehicle viewport. */ - DoCommandP(CMD_CLONE_VEHICLE, _vehicle_msg_translation_table[VCT_CMD_CLONE_VEH][v->type], + Command::Post(_vehicle_msg_translation_table[VCT_CMD_CLONE_VEH][v->type], _ctrl_pressed ? nullptr : CcCloneVehicle, - v->tile, v->index, _ctrl_pressed ? 1 : 0); + v->tile, v->index, _ctrl_pressed ? 1 : 0, {}); break; case WID_VV_TURN_AROUND: // turn around assert(v->IsGroundVehicle()); if (v->type == VEH_ROAD) { - DoCommandP(CMD_TURN_ROADVEH, _vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0); + Command::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0, {}); } else { - DoCommandP(CMD_REVERSE_TRAIN_DIRECTION, _vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0); + Command::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0, {}); } break; case WID_VV_FORCE_PROCEED: // force proceed assert(v->type == VEH_TRAIN); - DoCommandP(CMD_FORCE_TRAIN_PROCEED, STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index, 0); + Command::Post(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index, 0, {}); break; } } @@ -3014,7 +3017,7 @@ public: { if (str == nullptr) return; - DoCommandP(CMD_RENAME_VEHICLE, STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, 0, this->window_number, 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, 0, this->window_number, 0, str); } void OnMouseOver(Point pt, int widget) override diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp index 44e2718b68..673601f89f 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.cpp @@ -20,6 +20,7 @@ #include "company_base.h" #include "window_func.h" #include "waypoint_base.h" +#include "waypoint_cmd.h" #include "widgets/waypoint_widget.h" @@ -138,7 +139,7 @@ public: { if (str == nullptr) return; - DoCommandP(CMD_RENAME_WAYPOINT, STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME, 0, this->window_number, 0, str); + Command::Post(STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME, 0, this->window_number, 0, str); } }; From eab18f06a47e558fe313cb86c855e8949b01feed Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 31 Oct 2021 22:07:22 +0100 Subject: [PATCH 17/60] Codechange: Pass additional data as byte stream to command callbacks. --- src/ai/ai_instance.cpp | 10 ++++----- src/airport_gui.cpp | 2 +- src/bridge_gui.cpp | 11 ++++------ src/command_func.h | 7 ++----- src/command_type.h | 12 ++++++----- src/depot_gui.cpp | 5 +---- src/dock_gui.cpp | 4 ++-- src/game/game_instance.cpp | 10 ++++----- src/group_gui.cpp | 35 ++++++++++++++++++++------------ src/industry_gui.cpp | 9 ++++---- src/main_gui.cpp | 2 +- src/rail_gui.cpp | 9 ++++---- src/road_gui.cpp | 18 ++++++++-------- src/script/api/script_object.cpp | 16 +++++++-------- src/script/api/script_object.hpp | 4 ++-- src/script/script_instance.cpp | 6 +++--- src/script/script_instance.hpp | 5 ++--- src/script/script_storage.hpp | 5 +---- src/signs_cmd.cpp | 2 +- src/terraform_gui.cpp | 2 +- src/town_gui.cpp | 4 ++-- src/train_gui.cpp | 7 ++----- src/vehicle_gui.cpp | 13 +++++------- 23 files changed, 92 insertions(+), 106 deletions(-) diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index 509ed70d2e..576a81637f 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -92,14 +92,12 @@ ScriptInfo *AIInstance::FindLibrary(const char *library, int version) /** * DoCommand callback function for all commands executed by AIs. - * @param result The result of the command. * @param cmd cmd as given to DoCommandPInternal. + * @param result The result of the command. * @param tile The tile on which the command was executed. - * @param p1 p1 as given to DoCommandPInternal. - * @param p2 p2 as given to DoCommandPInternal. - * @param text text as given to DoCommandPInternal. + * @param data Command data as given to Command<>::Post. */ -void CcAI(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcAI(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { /* * The company might not exist anymore. Check for this. @@ -110,7 +108,7 @@ void CcAI(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, ui const Company *c = Company::GetIfValid(_current_company); if (c == nullptr || c->ai_instance == nullptr) return; - if (c->ai_instance->DoCommandCallback(result, tile, p1, p2, cmd)) { + if (c->ai_instance->DoCommandCallback(result, tile, data, cmd)) { c->ai_instance->Continue(); } } diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index af1fb1309f..0de11c9545 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -43,7 +43,7 @@ static void ShowBuildAirportPicker(Window *parent); SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout); -void CcBuildAirport(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcBuildAirport(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Failed()) return; diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index e9e1f48f5a..38ff698eb6 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -53,18 +53,15 @@ typedef GUIList GUIBridgeList; ///< List of bridges, used in #B * @param result Whether the build succeeded * @param cmd unused * @param end_tile End tile of the bridge. - * @param p1 packed start tile coords (~ dx) - * @param p2 various bitstuffed elements - * - p2 = (bit 0- 7) - bridge type (hi bh) - * - p2 = (bit 8-13) - rail type or road types. - * - p2 = (bit 15-16) - transport type. - * @param text unused + * @param data Additional bitstuffed command data. */ -void CcBuildBridge(const CommandCost &result, Commands cmd, TileIndex end_tile, uint32 p1, uint32 p2, const std::string &text) +void CcBuildBridge(Commands cmd, const CommandCost &result, TileIndex end_tile, const CommandDataBuffer &data) { if (result.Failed()) return; if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile); + auto [tile, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); + TransportType transport_type = Extract(p2); if (transport_type == TRANSPORT_ROAD) { diff --git a/src/command_func.h b/src/command_func.h index 6a9b93ff54..9d603abcf6 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -12,7 +12,7 @@ #include "command_type.h" #include "company_type.h" -#include +#include "misc/endian_buffer.hpp" #include "tile_map.h" /** @@ -34,9 +34,6 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); */ #define return_cmd_error(errcode) return CommandCost(errcode); -/** Storage buffer for serialized command data. */ -typedef std::vector CommandDataBuffer; - CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); @@ -213,7 +210,7 @@ protected: InternalPostResult(res, tile, estimate_only, only_sending, err_message, my_cmd); if (!estimate_only && !only_sending && callback != nullptr) { - std::apply(callback, std::tuple_cat(std::tuple{ res, Tcmd }, args)); + callback(Tcmd, res, tile, EndianBufferWriter::FromValue(args)); } return res.Succeeded(); diff --git a/src/command_type.h b/src/command_type.h index c182ca393e..59331dc7cc 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -13,6 +13,7 @@ #include "economy_type.h" #include "strings_type.h" #include "tile_type.h" +#include struct GRFFile; @@ -444,6 +445,9 @@ template struct CommandTraits; static inline constexpr const char *name = #proc_; \ }; +/** Storage buffer for serialized command data. */ +typedef std::vector CommandDataBuffer; + /** * Define a callback function for the client, after the command is finished. * @@ -451,14 +455,12 @@ template struct CommandTraits; * are from the #CommandProc callback type. The boolean parameter indicates if the * command succeeded or failed. * - * @param result The result of the executed command * @param cmd The command that was executed + * @param result The result of the executed command * @param tile The tile of the command action - * @param p1 Additional data of the command - * @param p1 Additional data of the command - * @param text Text of the command + * @param data Additional data of the command * @see CommandProc */ -typedef void CommandCallback(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); +typedef void CommandCallback(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data); #endif /* COMMAND_TYPE_H */ diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 76e03ef396..d316d97ca0 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -117,11 +117,8 @@ extern void DepotSortList(VehicleList *list); * @param result the result of the cloning command * @param cmd unused * @param tile unused - * @param p1 unused - * @param p2 unused - * @param text unused */ -void CcCloneVehicle(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcCloneVehicle(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Failed()) return; diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 3cb101f7ad..328ce1c20c 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -43,7 +43,7 @@ static void ShowBuildDocksDepotPicker(Window *parent); static Axis _ship_depot_direction; -void CcBuildDocks(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcBuildDocks(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Failed()) return; @@ -51,7 +51,7 @@ void CcBuildDocks(const CommandCost &result, Commands cmd, TileIndex tile, uint3 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } -void CcPlaySound_CONSTRUCTION_WATER(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcPlaySound_CONSTRUCTION_WATER(Commands cmd, const CommandCost &result,TileIndex tile, const CommandDataBuffer &) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_02_CONSTRUCTION_WATER, tile); } diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp index 47374525fa..8433567c7c 100644 --- a/src/game/game_instance.cpp +++ b/src/game/game_instance.cpp @@ -81,16 +81,14 @@ void GameInstance::Died() /** * DoCommand callback function for all commands executed by Game Scripts. - * @param result The result of the command. * @param cmd cmd as given to DoCommandPInternal. + * @param result The result of the command. * @param tile The tile on which the command was executed. - * @param p1 p1 as given to DoCommandPInternal. - * @param p2 p2 as given to DoCommandPInternal. - * @param text text as given to DoCommandPInternal. + * @param data Command data as given to Command<>::Post. */ -void CcGame(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcGame(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { - if (Game::GetGameInstance()->DoCommandCallback(result, tile, p1, p2, cmd)) { + if (Game::GetGameInstance()->DoCommandCallback(result, tile, data, cmd)) { Game::GetGameInstance()->Continue(); } } diff --git a/src/group_gui.cpp b/src/group_gui.cpp index b2deba3091..22f2889712 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -1141,38 +1141,47 @@ static inline VehicleGroupWindow *FindVehicleGroupWindow(VehicleType vt, Owner o /** * Opens a 'Rename group' window for newly created group. - * @param result Did command succeed? + * @param veh_type Vehicle type. + */ +static void CcCreateGroup(VehicleType veh_type) +{ + VehicleGroupWindow *w = FindVehicleGroupWindow(veh_type, _current_company); + if (w != nullptr) w->ShowRenameGroupWindow(_new_group_id, true); +} + +/** + * Opens a 'Rename group' window for newly created group. * @param cmd Unused. + * @param result Did command succeed? * @param tile Unused. - * @param p1 Vehicle type. - * @param p2 Unused. - * @param text Unused. + * @param data Command data. * @see CmdCreateGroup */ -void CcCreateGroup(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcCreateGroup(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { if (result.Failed()) return; + + auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); assert(p1 <= VEH_AIRCRAFT); - VehicleGroupWindow *w = FindVehicleGroupWindow((VehicleType)p1, _current_company); - if (w != nullptr) w->ShowRenameGroupWindow(_new_group_id, true); + CcCreateGroup((VehicleType)p1); } /** * Open rename window after adding a vehicle to a new group via drag and drop. - * @param result Did command succeed? * @param cmd Unused. + * @param result Did command succeed? * @param tile Unused. - * @param p1 Unused. - * @param p2 Bit 0-19: Vehicle ID. - * @param text Unused. + * @param data Command data. */ -void CcAddVehicleNewGroup(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcAddVehicleNewGroup(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { if (result.Failed()) return; + + auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); assert(Vehicle::IsValidID(GB(p2, 0, 20))); - CcCreateGroup(result, cmd, 0, Vehicle::Get(GB(p2, 0, 20))->type, 0, text); + CcCreateGroup(Vehicle::Get(GB(p2, 0, 20))->type); } /** diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 29da3c76ef..b66d4f8bfc 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -219,17 +219,16 @@ void SortIndustryTypes() /** * Command callback. In case of failure to build an industry, show an error message. - * @param result Result of the command. * @param cmd Unused. + * @param result Result of the command. * @param tile Tile where the industry is placed. - * @param p1 Additional data of the #CMD_BUILD_INDUSTRY command. - * @param p2 Additional data of the #CMD_BUILD_INDUSTRY command. - * @param text Unused. + * @param data Additional data of the #CMD_BUILD_INDUSTRY command. */ -void CcBuildIndustry(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcBuildIndustry(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { if (result.Succeeded()) return; + auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); uint8 indtype = GB(p1, 0, 8); if (indtype < NUM_INDUSTRYTYPES) { const IndustrySpec *indsp = GetIndustrySpec(indtype); diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 847d328454..680493c12c 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -77,7 +77,7 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl } -void CcPlaySound_EXPLOSION(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcPlaySound_EXPLOSION(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_12_EXPLOSION, tile); } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index a57e2f8e53..c1c45d5d72 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -89,7 +89,7 @@ static bool IsStationAvailable(const StationSpec *statspec) return Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res); } -void CcPlaySound_CONSTRUCTION_RAIL(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcPlaySound_CONSTRUCTION_RAIL(Commands cmd, const CommandCost &result,TileIndex tile, const CommandDataBuffer &) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); } @@ -135,10 +135,11 @@ static const DiagDirection _place_depot_extra_dir[12] = { DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_NW, DIAGDIR_NE, }; -void CcRailDepot(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcRailDepot(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { if (result.Failed()) return; + auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); DiagDirection dir = (DiagDirection)p2; if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); @@ -176,7 +177,7 @@ static void PlaceRail_Waypoint(TileIndex tile) } } -void CcStation(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcStation(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Failed()) return; @@ -293,7 +294,7 @@ static void PlaceRail_Bridge(TileIndex tile, Window *w) } /** Command callback for building a tunnel */ -void CcBuildRailTunnel(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcBuildRailTunnel(Commands cmd, const CommandCost &result,TileIndex tile, const CommandDataBuffer &) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 948095f773..a777c9c1d1 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -69,7 +69,7 @@ static RoadType _cur_roadtype; static DiagDirection _road_depot_orientation; static DiagDirection _road_station_picker_orientation; -void CcPlaySound_CONSTRUCTION_OTHER(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcPlaySound_CONSTRUCTION_OTHER(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); } @@ -92,15 +92,11 @@ static void PlaceRoad_Bridge(TileIndex tile, Window *w) /** * Callback executed after a build road tunnel command has been called. * - * @param result Whether the build succeeded. * @param cmd unused + * @param result Whether the build succeeded. * @param start_tile Starting tile of the tunnel. - * @param p1 bit 0-3 railtype or roadtypes - * bit 8-9 transport type - * @param p2 unused - * @param text unused */ -void CcBuildRoadTunnel(const CommandCost &result, Commands cmd, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) +void CcBuildRoadTunnel(Commands cmd, const CommandCost &result, TileIndex start_tile, const CommandDataBuffer &) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, start_tile); @@ -133,10 +129,12 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) } } -void CcRoadDepot(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { if (result.Failed()) return; + auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); + DiagDirection dir = (DiagDirection)GB(p1, 0, 2); if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); @@ -160,10 +158,12 @@ void CcRoadDepot(const CommandCost &result, Commands cmd, TileIndex tile, uint32 * @param text Unused. * @see CmdBuildRoadStop */ -void CcRoadStop(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { if (result.Failed()) return; + auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); + DiagDirection dir = (DiagDirection)GB(p2, 3, 2); if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index 56fdde8261..c63d2a2ea8 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -82,24 +82,22 @@ ScriptObject::ActiveInstance::~ActiveInstance() return GetStorage()->mode_instance; } -/* static */ void ScriptObject::SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +/* static */ void ScriptObject::SetLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd) { ScriptStorage *s = GetStorage(); - Debug(script, 6, "SetLastCommand company={:02d} tile={:06x} p1={:08x} p2={:08x} cmd={}", s->root_company, tile, p1, p2, cmd); + Debug(script, 6, "SetLastCommand company={:02d} tile={:06x} cmd={} data={}", s->root_company, tile, cmd, FormatArrayAsHex(data)); s->last_tile = tile; - s->last_p1 = p1; - s->last_p2 = p2; + s->last_data = data; s->last_cmd = cmd; } -/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd) { ScriptStorage *s = GetStorage(); - Debug(script, 6, "CheckLastCommand company={:02d} tile={:06x} p1={:08x} p2={:08x} cmd={}", s->root_company, tile, p1, p2, cmd); + Debug(script, 6, "CheckLastCommand company={:02d} tile={:06x} cmd={} data={}", s->root_company, tile, cmd, FormatArrayAsHex(data)); if (s->last_tile != tile) return false; - if (s->last_p1 != p1) return false; - if (s->last_p2 != p2) return false; if (s->last_cmd != cmd) return false; + if (s->last_data != data) return false; return true; } @@ -326,7 +324,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() if (GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = UINT32_MAX; /* Store the command for command callback validation. */ - if (!estimate_only && _networking && !_generating_world) SetLastCommand(tile, p1, p2, cmd); + if (!estimate_only && _networking && !_generating_world) SetLastCommand(tile, EndianBufferWriter::FromValue(std::make_tuple(tile, p1, p2, command_text)), cmd); /* Try to perform the command. */ CommandCost res = ::DoCommandPInternal(cmd, STR_NULL, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, false, estimate_only, false, tile, p1, p2, command_text); diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index a1134aa5c3..40c8eaf854 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -75,12 +75,12 @@ protected: /** * Store the latest command executed by the script. */ - static void SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd); + static void SetLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd); /** * Check if it's the latest command executed by the script. */ - static bool CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd); + static bool CheckLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd); /** * Sets the DoCommand costs counter to a value. diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index 03fad1491a..ecf846b9fd 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -687,11 +687,11 @@ SQInteger ScriptInstance::GetOpsTillSuspend() return this->engine->GetOpsTillSuspend(); } -bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd) +bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, Commands cmd) { ScriptObject::ActiveInstance active(this); - if (!ScriptObject::CheckLastCommand(tile, p1, p2, cmd)) { + if (!ScriptObject::CheckLastCommand(tile, data, cmd)) { Debug(script, 1, "DoCommandCallback terminating a script, last command does not match expected command"); return false; } @@ -705,7 +705,7 @@ bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile ScriptObject::SetLastCost(result.GetCost()); } - ScriptObject::SetLastCommand(INVALID_TILE, 0, 0, CMD_END); + ScriptObject::SetLastCommand(INVALID_TILE, {}, CMD_END); return true; } diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp index 01415d4d4b..c30fd14996 100644 --- a/src/script/script_instance.hpp +++ b/src/script/script_instance.hpp @@ -178,12 +178,11 @@ public: * DoCommand callback function for all commands executed by scripts. * @param result The result of the command. * @param tile The tile on which the command was executed. - * @param p1 p1 as given to DoCommandPInternal. - * @param p2 p2 as given to DoCommandPInternal. + * @param data Command data as given to DoCommandPInternal. * @param cmd cmd as given to DoCommandPInternal. * @return true if we handled result. */ - bool DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, Commands cmd); + bool DoCommandCallback(const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, Commands cmd); /** * Insert an event for this script. diff --git a/src/script/script_storage.hpp b/src/script/script_storage.hpp index 8dadf59ae4..3735adc1da 100644 --- a/src/script/script_storage.hpp +++ b/src/script/script_storage.hpp @@ -45,8 +45,7 @@ private: bool last_command_res; ///< The last result of the command. TileIndex last_tile; ///< The last tile passed to a command. - uint32 last_p1; ///< The last p1 passed to a command. - uint32 last_p2; ///< The last p2 passed to a command. + CommandDataBuffer last_data; ///< The last data passed to a command. Commands last_cmd; ///< The last cmd passed to a command. VehicleID new_vehicle_id; ///< The ID of the new Vehicle. @@ -77,8 +76,6 @@ public: last_error (STR_NULL), last_command_res (true), last_tile (INVALID_TILE), - last_p1 (0), - last_p2 (0), last_cmd (CMD_END), new_vehicle_id (0), new_sign_id (0), diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index 4fdfc0ab5f..00baf45a88 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -116,7 +116,7 @@ CommandCost CmdRenameSign(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 * @param p2 unused * @param text unused */ -void CcPlaceSign(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcPlaceSign(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Failed()) return; diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index c65adad7d1..7399d6ffa2 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -44,7 +44,7 @@ #include "safeguards.h" -void CcTerraform(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcTerraform(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 8f315a0557..6e955e103e 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -1009,7 +1009,7 @@ void ShowTownDirectory() new TownDirectoryWindow(&_town_directory_desc); } -void CcFoundTown(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcFoundTown(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Failed()) return; @@ -1017,7 +1017,7 @@ void CcFoundTown(const CommandCost &result, Commands cmd, TileIndex tile, uint32 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } -void CcFoundRandomTown(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcFoundRandomTown(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Succeeded()) ScrollMainWindowToTile(Town::Get(_new_town_id)->xy); } diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 8fc97d8571..e41bdf6aca 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -22,14 +22,11 @@ /** * Callback for building wagons. - * @param result The result of the command. * @param cmd Unused. + * @param result The result of the command. * @param tile The tile the command was executed on. - * @param p1 Additional data for the command (for the #CommandProc) - * @param p2 Additional data for the command (for the #CommandProc) - * @param text Unused. */ -void CcBuildWagon(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcBuildWagon(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) { if (result.Failed()) return; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index c549101504..80b75e7ce8 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2622,14 +2622,13 @@ static const StringID _vehicle_msg_translation_table[][4] = { * @param result the result of the start/stop command * @param cmd unused * @param tile unused - * @param p1 vehicle ID - * @param p2 unused - * @param text unused + * @param data Command data */ -void CcStartStopVehicle(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcStartStopVehicle(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { if (result.Failed()) return; + auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); const Vehicle *v = Vehicle::GetIfValid(p1); if (v == nullptr || !v->IsPrimaryVehicle() || v->owner != _local_company) return; @@ -3127,11 +3126,9 @@ void StopGlobalFollowVehicle(const Vehicle *v) * @param result indicates completion (or not) of the operation * @param cmd unused * @param tile unused - * @param p1 unused - * @param p2 unused - * @param text unused + * @param data unused */ -void CcBuildPrimaryVehicle(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { if (result.Failed()) return; From 6691ee3b963ee3282490360bb3cc1ea09d0c58ea Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Mon, 1 Nov 2021 21:30:34 +0100 Subject: [PATCH 18/60] Codechange: Template script command calls. --- src/script/api/script_airport.cpp | 6 +- src/script/api/script_basestation.cpp | 8 ++- src/script/api/script_bridge.cpp | 13 +++-- src/script/api/script_company.cpp | 32 +++++----- src/script/api/script_controller.cpp | 3 +- src/script/api/script_engine.cpp | 5 +- src/script/api/script_event_types.cpp | 6 +- src/script/api/script_game.cpp | 5 +- src/script/api/script_gamesettings.cpp | 3 +- src/script/api/script_goal.cpp | 15 ++--- src/script/api/script_group.cpp | 25 ++++---- src/script/api/script_industry.cpp | 9 +-- src/script/api/script_industrytype.cpp | 5 +- src/script/api/script_marine.cpp | 25 ++++---- src/script/api/script_news.cpp | 3 +- src/script/api/script_object.cpp | 36 +++++------- src/script/api/script_object.hpp | 81 +++++++++++++++++++++++++- src/script/api/script_objecttype.cpp | 3 +- src/script/api/script_order.cpp | 37 ++++++------ src/script/api/script_rail.cpp | 31 +++++----- src/script/api/script_road.cpp | 19 +++--- src/script/api/script_sign.cpp | 7 ++- src/script/api/script_station.cpp | 3 +- src/script/api/script_story_page.cpp | 30 +++++----- src/script/api/script_subsidy.cpp | 3 +- src/script/api/script_tile.cpp | 15 +++-- src/script/api/script_town.cpp | 17 +++--- src/script/api/script_tunnel.cpp | 13 +++-- src/script/api/script_vehicle.cpp | 26 +++++---- src/script/api/script_viewport.cpp | 7 ++- 30 files changed, 308 insertions(+), 183 deletions(-) diff --git a/src/script/api/script_airport.cpp b/src/script/api/script_airport.cpp index 9477191724..5927b16620 100644 --- a/src/script/api/script_airport.cpp +++ b/src/script/api/script_airport.cpp @@ -12,6 +12,8 @@ #include "script_station.hpp" #include "../../station_base.h" #include "../../town.h" +#include "../../landscape_cmd.h" +#include "../../station_cmd.h" #include "../../safeguards.h" @@ -77,7 +79,7 @@ uint p2 = station_id == ScriptStation::STATION_JOIN_ADJACENT ? 0 : 1; p2 |= (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; - return ScriptObject::DoCommand(tile, type, p2, CMD_BUILD_AIRPORT); + return ScriptObject::Command::Do(tile, type, p2, {}); } /* static */ bool ScriptAirport::RemoveAirport(TileIndex tile) @@ -86,7 +88,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)) EnforcePrecondition(false, IsAirportTile(tile) || IsHangarTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ int32 ScriptAirport::GetNumHangars(TileIndex tile) diff --git a/src/script/api/script_basestation.cpp b/src/script/api/script_basestation.cpp index 860e54c787..a249344101 100644 --- a/src/script/api/script_basestation.cpp +++ b/src/script/api/script_basestation.cpp @@ -13,6 +13,8 @@ #include "../../station_base.h" #include "../../string_func.h" #include "../../strings_func.h" +#include "../../station_cmd.h" +#include "../../waypoint_cmd.h" #include "table/strings.h" #include "../../safeguards.h" @@ -42,7 +44,11 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_STATION_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::DoCommand(0, station_id, 0, ::Station::IsValidID(station_id) ? CMD_RENAME_STATION : CMD_RENAME_WAYPOINT, text); + if (::Station::IsValidID(station_id)) { + return ScriptObject::Command::Do(0, station_id, 0, text); + } else { + return ScriptObject::Command::Do(0, station_id, 0, text); + } } /* static */ TileIndex ScriptBaseStation::GetLocation(StationID station_id) diff --git a/src/script/api/script_bridge.cpp b/src/script/api/script_bridge.cpp index 4d685ca21f..dc357c2552 100644 --- a/src/script/api/script_bridge.cpp +++ b/src/script/api/script_bridge.cpp @@ -14,6 +14,9 @@ #include "../../bridge_map.h" #include "../../strings_func.h" #include "../../date_func.h" +#include "../../landscape_cmd.h" +#include "../../road_cmd.h" +#include "../../tunnelbridge_cmd.h" #include "table/strings.h" #include "../../safeguards.h" @@ -95,12 +98,12 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) /* For rail and water we do nothing special */ if (vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER) { - return ScriptObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE); + return ScriptObject::Command::Do(end, start, type | bridge_id, {}); } ScriptObject::SetCallbackVariable(0, start); ScriptObject::SetCallbackVariable(1, end); - return ScriptObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, nullptr, &::_DoCommandReturnBuildBridge1); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildBridge1, end, start, type | bridge_id, {}); } /* static */ bool ScriptBridge::_BuildBridgeRoad1() @@ -112,7 +115,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptRoad::GetCurrentRoadType() << 4), 0, CMD_BUILD_ROAD, nullptr, &::_DoCommandReturnBuildBridge2); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildBridge2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptRoad::GetCurrentRoadType() << 4), 0, {}); } /* static */ bool ScriptBridge::_BuildBridgeRoad2() @@ -124,14 +127,14 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptRoad::GetCurrentRoadType() << 4), 0, CMD_BUILD_ROAD); + return ScriptObject::Command::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptRoad::GetCurrentRoadType() << 4), 0, {}); } /* static */ bool ScriptBridge::RemoveBridge(TileIndex tile) { EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsBridgeTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ char *ScriptBridge::GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type) diff --git a/src/script/api/script_company.cpp b/src/script/api/script_company.cpp index 876ad84c5e..c8f8a616fb 100644 --- a/src/script/api/script_company.cpp +++ b/src/script/api/script_company.cpp @@ -20,6 +20,10 @@ #include "../../tile_map.h" #include "../../string_func.h" #include "../../settings_func.h" +#include "../../company_cmd.h" +#include "../../misc_cmd.h" +#include "../../object_cmd.h" +#include "../../settings_cmd.h" #include "table/strings.h" #include "../../safeguards.h" @@ -48,7 +52,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_COMPANY_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::DoCommand(0, 0, 0, CMD_RENAME_COMPANY, text); + return ScriptObject::Command::Do(0, 0, 0, text); } /* static */ char *ScriptCompany::GetName(ScriptCompany::CompanyID company) @@ -69,7 +73,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_PRESIDENT_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::DoCommand(0, 0, 0, CMD_RENAME_PRESIDENT, text); + return ScriptObject::Command::Do(0, 0, 0, text); } /* static */ char *ScriptCompany::GetPresidentName(ScriptCompany::CompanyID company) @@ -97,7 +101,7 @@ GenderEthnicity ge = (GenderEthnicity)((gender == GENDER_FEMALE ? (1 << ::GENDER_FEMALE) : 0) | (::InteractiveRandom() & (1 << ETHNICITY_BLACK))); RandomCompanyManagerFaceBits(cmf, ge, false); - return ScriptObject::DoCommand(0, 0, cmf, CMD_SET_COMPANY_MANAGER_FACE); + return ScriptObject::Command::Do(0, 0, cmf, {}); } /* static */ ScriptCompany::Gender ScriptCompany::GetPresidentGender(CompanyID company) @@ -206,9 +210,11 @@ Money amount = abs(loan - GetLoanAmount()); - return ScriptObject::DoCommand(0, - amount >> 32, (amount & 0xFFFFFFFC) | 2, - (loan > GetLoanAmount()) ? CMD_INCREASE_LOAN : CMD_DECREASE_LOAN); + if (loan > GetLoanAmount()) { + return ScriptObject::Command::Do(0, amount >> 32, (amount & 0xFFFFFFFC) | 2, {}); + } else { + return ScriptObject::Command::Do(0, amount >> 32, (amount & 0xFFFFFFFC) | 2, {}); + } } /* static */ bool ScriptCompany::SetMinimumLoanAmount(Money loan) @@ -238,7 +244,7 @@ EnforcePrecondition(false, company != COMPANY_INVALID); /* Network commands only allow 0 to indicate invalid tiles, not INVALID_TILE */ - return ScriptObject::DoCommand(tile == INVALID_TILE ? (TileIndex)0U : tile , (uint32)(delta), company | expenses_type << 8 , CMD_CHANGE_BANK_BALANCE); + return ScriptObject::Command::Do(tile == INVALID_TILE ? (TileIndex)0U : tile, (uint32)(delta), company | expenses_type << 8, {}); } /* static */ bool ScriptCompany::BuildCompanyHQ(TileIndex tile) @@ -246,7 +252,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::DoCommand(tile, OBJECT_HQ, 0, CMD_BUILD_OBJECT); + return ScriptObject::Command::Do(tile, OBJECT_HQ, 0, {}); } /* static */ TileIndex ScriptCompany::GetCompanyHQ(CompanyID company) @@ -260,7 +266,7 @@ /* static */ bool ScriptCompany::SetAutoRenewStatus(bool autorenew) { - return ScriptObject::DoCommand(0, 0, autorenew ? 1 : 0, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew"); + return ScriptObject::Command::Do(0, 0, autorenew ? 1 : 0, "company.engine_renew"); } /* static */ bool ScriptCompany::GetAutoRenewStatus(CompanyID company) @@ -273,7 +279,7 @@ /* static */ bool ScriptCompany::SetAutoRenewMonths(int16 months) { - return ScriptObject::DoCommand(0, 0, months, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew_months"); + return ScriptObject::Command::Do(0, 0, months, "company.engine_renew_months"); } /* static */ int16 ScriptCompany::GetAutoRenewMonths(CompanyID company) @@ -288,7 +294,7 @@ { EnforcePrecondition(false, money >= 0); EnforcePrecondition(false, (int64)money <= UINT32_MAX); - return ScriptObject::DoCommand(0, 0, money, CMD_CHANGE_COMPANY_SETTING, "company.engine_renew_money"); + return ScriptObject::Command::Do(0, 0, money, "company.engine_renew_money"); } /* static */ Money ScriptCompany::GetAutoRenewMoney(CompanyID company) @@ -301,12 +307,12 @@ /* static */ bool ScriptCompany::SetPrimaryLiveryColour(LiveryScheme scheme, Colours colour) { - return ScriptObject::DoCommand(0, scheme, colour, CMD_SET_COMPANY_COLOUR); + return ScriptObject::Command::Do(0, scheme, colour, {}); } /* static */ bool ScriptCompany::SetSecondaryLiveryColour(LiveryScheme scheme, Colours colour) { - return ScriptObject::DoCommand(0, scheme | 1 << 8, colour, CMD_SET_COMPANY_COLOUR); + return ScriptObject::Command::Do(0, scheme | 1 << 8, colour, {}); } /* static */ ScriptCompany::Colours ScriptCompany::GetPrimaryLiveryColour(ScriptCompany::LiveryScheme scheme) diff --git a/src/script/api/script_controller.cpp b/src/script/api/script_controller.cpp index 8af7b87a3c..74a3ad3ea8 100644 --- a/src/script/api/script_controller.cpp +++ b/src/script/api/script_controller.cpp @@ -21,6 +21,7 @@ #include "../../ai/ai_gui.hpp" #include "../../settings_type.h" #include "../../network/network.h" +#include "../../misc_cmd.h" #include "../../safeguards.h" @@ -59,7 +60,7 @@ ShowAIDebugWindow(ScriptObject::GetRootCompany()); if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - ScriptObject::DoCommand(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); + ScriptObject::Command::Do(0, PM_PAUSED_NORMAL, 1, {}); } } diff --git a/src/script/api/script_engine.cpp b/src/script/api/script_engine.cpp index 1ec1b23a8e..d6cab36b6c 100644 --- a/src/script/api/script_engine.cpp +++ b/src/script/api/script_engine.cpp @@ -17,6 +17,7 @@ #include "../../engine_base.h" #include "../../engine_func.h" #include "../../articulated_vehicles.h" +#include "../../engine_cmd.h" #include "table/strings.h" #include "../../safeguards.h" @@ -285,7 +286,7 @@ EnforcePrecondition(false, IsValidEngine(engine_id)); EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); - return ScriptObject::DoCommand(0, engine_id, (uint32)company | (1 << 31), CMD_ENGINE_CTRL); + return ScriptObject::Command::Do(0, engine_id, (uint32)company | (1 << 31), {}); } /* static */ bool ScriptEngine::DisableForCompany(EngineID engine_id, ScriptCompany::CompanyID company) @@ -296,5 +297,5 @@ EnforcePrecondition(false, IsValidEngine(engine_id)); EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); - return ScriptObject::DoCommand(0, engine_id, company, CMD_ENGINE_CTRL); + return ScriptObject::Command::Do(0, engine_id, company, {}); } diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp index 3cc5287eb8..f7776c40e8 100644 --- a/src/script/api/script_event_types.cpp +++ b/src/script/api/script_event_types.cpp @@ -16,6 +16,8 @@ #include "../../engine_base.h" #include "../../articulated_vehicles.h" #include "../../string_func.h" +#include "../../economy_cmd.h" +#include "../../engine_cmd.h" #include "table/strings.h" #include "../../safeguards.h" @@ -110,12 +112,12 @@ int32 ScriptEventEnginePreview::GetVehicleType() bool ScriptEventEnginePreview::AcceptPreview() { if (!this->IsEngineValid()) return false; - return ScriptObject::DoCommand(0, this->engine, 0, CMD_WANT_ENGINE_PREVIEW); + return ScriptObject::Command::Do(0, this->engine, 0, {}); } bool ScriptEventCompanyAskMerger::AcceptMerger() { - return ScriptObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY); + return ScriptObject::Command::Do(0, this->owner, 0, {}); } ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) : diff --git a/src/script/api/script_game.cpp b/src/script/api/script_game.cpp index 43674c6f37..9b40a1cd3b 100644 --- a/src/script/api/script_game.cpp +++ b/src/script/api/script_game.cpp @@ -12,17 +12,18 @@ #include "../../command_type.h" #include "../../settings_type.h" #include "../../network/network.h" +#include "../../misc_cmd.h" #include "../../safeguards.h" /* static */ bool ScriptGame::Pause() { - return ScriptObject::DoCommand(0, PM_PAUSED_GAME_SCRIPT, 1, CMD_PAUSE); + return ScriptObject::Command::Do(0, PM_PAUSED_GAME_SCRIPT, 1, {}); } /* static */ bool ScriptGame::Unpause() { - return ScriptObject::DoCommand(0, PM_PAUSED_GAME_SCRIPT, 0, CMD_PAUSE); + return ScriptObject::Command::Do(0, PM_PAUSED_GAME_SCRIPT, 0, {}); } /* static */ bool ScriptGame::IsPaused() diff --git a/src/script/api/script_gamesettings.cpp b/src/script/api/script_gamesettings.cpp index 78b26e9bb3..611b78b8b6 100644 --- a/src/script/api/script_gamesettings.cpp +++ b/src/script/api/script_gamesettings.cpp @@ -12,6 +12,7 @@ #include "../../settings_internal.h" #include "../../settings_type.h" #include "../../command_type.h" +#include "../../settings_cmd.h" #include "../../safeguards.h" @@ -37,7 +38,7 @@ if ((sd->flags & SF_NO_NETWORK_SYNC) != 0) return false; - return ScriptObject::DoCommand(0, 0, value, CMD_CHANGE_SETTING, sd->GetName().c_str()); + return ScriptObject::Command::Do(0, 0, value, sd->GetName()); } /* static */ bool ScriptGameSettings::IsDisabledVehicleType(ScriptVehicle::VehicleType vehicle_type) diff --git a/src/script/api/script_goal.cpp b/src/script/api/script_goal.cpp index f1b75b032f..dbc2c51e01 100644 --- a/src/script/api/script_goal.cpp +++ b/src/script/api/script_goal.cpp @@ -19,6 +19,7 @@ #include "../../goal_base.h" #include "../../string_func.h" #include "../../network/network_base.h" +#include "../../goal_cmd.h" #include "../../safeguards.h" @@ -49,7 +50,7 @@ (type == GT_COMPANY && ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)destination) != ScriptCompany::COMPANY_INVALID) || (type == GT_STORY_PAGE && story_page != nullptr && (c == INVALID_COMPANY ? story_page->company == INVALID_COMPANY : story_page->company == INVALID_COMPANY || story_page->company == c))); - if (!ScriptObject::DoCommand(0, type | (c << 8), destination, CMD_CREATE_GOAL, text, &ScriptInstance::DoCommandReturnGoalID)) return GOAL_INVALID; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnGoalID, 0, type | (c << 8), destination, text)) return GOAL_INVALID; /* In case of test-mode, we return GoalID 0 */ return (ScriptGoal::GoalID)0; @@ -60,7 +61,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); EnforcePrecondition(false, IsValidGoal(goal_id)); - return ScriptObject::DoCommand(0, goal_id, 0, CMD_REMOVE_GOAL); + return ScriptObject::Command::Do(0, goal_id, 0, {}); } /* static */ bool ScriptGoal::SetText(GoalID goal_id, Text *goal) @@ -72,7 +73,7 @@ EnforcePrecondition(false, goal != nullptr); EnforcePrecondition(false, !StrEmpty(goal->GetEncodedText())); - return ScriptObject::DoCommand(0, goal_id, 0, CMD_SET_GOAL_TEXT, goal->GetEncodedText()); + return ScriptObject::Command::Do(0, goal_id, 0, goal->GetEncodedText()); } /* static */ bool ScriptGoal::SetProgress(GoalID goal_id, Text *progress) @@ -87,7 +88,7 @@ progress = nullptr; } - return ScriptObject::DoCommand(0, goal_id, 0, CMD_SET_GOAL_PROGRESS, progress != nullptr ? progress->GetEncodedText() : nullptr); + return ScriptObject::Command::Do(0, goal_id, 0, progress != nullptr ? std::string{ progress->GetEncodedText() } : std::string{}); } /* static */ bool ScriptGoal::SetCompleted(GoalID goal_id, bool completed) @@ -95,7 +96,7 @@ EnforcePrecondition(false, IsValidGoal(goal_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::DoCommand(0, goal_id, completed ? 1 : 0, CMD_SET_GOAL_COMPLETED); + return ScriptObject::Command::Do(0, goal_id, completed ? 1 : 0, {}); } /* static */ bool ScriptGoal::IsCompleted(GoalID goal_id) @@ -120,7 +121,7 @@ EnforcePrecondition(false, buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT)); EnforcePrecondition(false, (int)type < ::GQT_END); - return ScriptObject::DoCommand(0, uniqueid | (target << 16), buttons | (type << 29) | (is_client ? (1 << 31) : 0), CMD_GOAL_QUESTION, text); + return ScriptObject::Command::Do(0, uniqueid | (target << 16), buttons | (type << 29) | (is_client ? (1 << 31) : 0), text); } /* static */ bool ScriptGoal::Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons) @@ -145,5 +146,5 @@ { EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::DoCommand(0, uniqueid, 0, CMD_GOAL_QUESTION_ANSWER); + return ScriptObject::Command::Do(0, uniqueid, 0, {}); } diff --git a/src/script/api/script_group.cpp b/src/script/api/script_group.cpp index a6e2fdee25..f4535c35e4 100644 --- a/src/script/api/script_group.cpp +++ b/src/script/api/script_group.cpp @@ -16,6 +16,9 @@ #include "../../autoreplace_func.h" #include "../../settings_func.h" #include "../../vehicle_base.h" +#include "../../autoreplace_cmd.h" +#include "../../group_cmd.h" +#include "../../settings_cmd.h" #include "table/strings.h" #include "../../safeguards.h" @@ -28,7 +31,7 @@ /* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id) { - if (!ScriptObject::DoCommand(0, (::VehicleType)vehicle_type, parent_group_id, CMD_CREATE_GROUP, nullptr, &ScriptInstance::DoCommandReturnGroupID)) return GROUP_INVALID; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnGroupID, 0, (::VehicleType)vehicle_type, parent_group_id, {})) return GROUP_INVALID; /* In case of test-mode, we return GroupID 0 */ return (ScriptGroup::GroupID)0; @@ -38,7 +41,7 @@ { EnforcePrecondition(false, IsValidGroup(group_id)); - return ScriptObject::DoCommand(0, group_id, 0, CMD_DELETE_GROUP); + return ScriptObject::Command::Do(0, group_id, 0, {}); } /* static */ ScriptVehicle::VehicleType ScriptGroup::GetVehicleType(GroupID group_id) @@ -58,7 +61,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_GROUP_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::DoCommand(0, group_id, 0, CMD_ALTER_GROUP, text); + return ScriptObject::Command::Do(0, group_id, 0, text); } /* static */ char *ScriptGroup::GetName(GroupID group_id) @@ -74,7 +77,7 @@ EnforcePrecondition(false, IsValidGroup(group_id)); EnforcePrecondition(false, IsValidGroup(parent_group_id)); - return ScriptObject::DoCommand(0, group_id | 1 << 16, parent_group_id, CMD_ALTER_GROUP); + return ScriptObject::Command::Do(0, group_id | 1 << 16, parent_group_id, {}); } /* static */ ScriptGroup::GroupID ScriptGroup::GetParent(GroupID group_id) @@ -89,7 +92,7 @@ { EnforcePrecondition(false, IsValidGroup(group_id)); - return ScriptObject::DoCommand(0, group_id | GroupFlags::GF_REPLACE_PROTECTION, enable ? 1 : 0, CMD_SET_GROUP_FLAG); + return ScriptObject::Command::Do(0, group_id | GroupFlags::GF_REPLACE_PROTECTION, enable ? 1 : 0, {}); } /* static */ bool ScriptGroup::GetAutoReplaceProtection(GroupID group_id) @@ -120,14 +123,14 @@ EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT); EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); - return ScriptObject::DoCommand(0, group_id, vehicle_id, CMD_ADD_VEHICLE_GROUP); + return ScriptObject::Command::Do(0, group_id, vehicle_id, {}); } /* static */ bool ScriptGroup::EnableWagonRemoval(bool enable_removal) { if (HasWagonRemoval() == enable_removal) return true; - return ScriptObject::DoCommand(0, 0, enable_removal ? 1 : 0, CMD_CHANGE_COMPANY_SETTING, "company.renew_keep_length"); + return ScriptObject::Command::Do(0, 0, enable_removal ? 1 : 0, "company.renew_keep_length"); } /* static */ bool ScriptGroup::HasWagonRemoval() @@ -140,7 +143,7 @@ EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL); EnforcePrecondition(false, ScriptEngine::IsBuildable(engine_id_new)); - return ScriptObject::DoCommand(0, group_id << 16, (engine_id_new << 16) | engine_id_old, CMD_SET_AUTOREPLACE); + return ScriptObject::Command::Do(0, group_id << 16, (engine_id_new << 16) | engine_id_old, {}); } /* static */ EngineID ScriptGroup::GetEngineReplacement(GroupID group_id, EngineID engine_id) @@ -154,7 +157,7 @@ { EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL); - return ScriptObject::DoCommand(0, group_id << 16, (::INVALID_ENGINE << 16) | engine_id, CMD_SET_AUTOREPLACE); + return ScriptObject::Command::Do(0, group_id << 16, (::INVALID_ENGINE << 16) | engine_id, {}); } /* static */ Money ScriptGroup::GetProfitThisYear(GroupID group_id) @@ -204,14 +207,14 @@ { EnforcePrecondition(false, IsValidGroup(group_id)); - return ScriptObject::DoCommand(0, group_id, colour << 16, CMD_SET_GROUP_LIVERY); + return ScriptObject::Command::Do(0, group_id, colour << 16, {}); } /* static */ bool ScriptGroup::SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour) { EnforcePrecondition(false, IsValidGroup(group_id)); - return ScriptObject::DoCommand(0, group_id, (1 << 8) | (colour << 16), CMD_SET_GROUP_LIVERY); + return ScriptObject::Command::Do(0, group_id, (1 << 8) | (colour << 16), {}); } /* static */ ScriptCompany::Colours ScriptGroup::GetPrimaryColour(GroupID group_id) diff --git a/src/script/api/script_industry.cpp b/src/script/api/script_industry.cpp index 6f54fda14c..afcaee5547 100644 --- a/src/script/api/script_industry.cpp +++ b/src/script/api/script_industry.cpp @@ -19,6 +19,7 @@ #include "../../strings_func.h" #include "../../station_base.h" #include "../../newgrf_industries.h" +#include "../../industry_cmd.h" #include "table/strings.h" #include @@ -59,7 +60,7 @@ } EnforcePrecondition(false, IsValidIndustry(industry_id)); - return ScriptObject::DoCommand(0, industry_id, static_cast(IndustryAction::SetText), CMD_INDUSTRY_CTRL, encoded_text); + return ScriptObject::Command::Do(0, industry_id, static_cast(IndustryAction::SetText), std::string{ encoded_text ? encoded_text : "" }); } /* static */ ScriptIndustry::CargoAcceptState ScriptIndustry::IsCargoAccepted(IndustryID industry_id, CargoID cargo_id) @@ -257,7 +258,7 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag if (ScriptObject::GetCompany() != OWNER_DEITY) return false; if (!IsValidIndustry(industry_id)) return false; - return ScriptObject::DoCommand(0, industry_id, 0 | ((control_flags & ::INDCTL_MASK) << 8), CMD_INDUSTRY_CTRL); + return ScriptObject::Command::Do(0, industry_id, 0 | ((control_flags & ::INDCTL_MASK) << 8), {}); } /* static */ ScriptCompany::CompanyID ScriptIndustry::GetExclusiveSupplier(IndustryID industry_id) @@ -276,7 +277,7 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag auto company = ScriptCompany::ResolveCompanyID(company_id); ::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company); - return ScriptObject::DoCommand(0, industry_id, 1 | (((uint8)owner) << 16), CMD_INDUSTRY_CTRL); + return ScriptObject::Command::Do(0, industry_id, 1 | (((uint8)owner) << 16), {}); } /* static */ ScriptCompany::CompanyID ScriptIndustry::GetExclusiveConsumer(IndustryID industry_id) @@ -295,5 +296,5 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag auto company = ScriptCompany::ResolveCompanyID(company_id); ::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company); - return ScriptObject::DoCommand(0, industry_id, 2 | (((uint8)owner) << 16), CMD_INDUSTRY_CTRL); + return ScriptObject::Command::Do(0, industry_id, 2 | (((uint8)owner) << 16), {}); } diff --git a/src/script/api/script_industrytype.cpp b/src/script/api/script_industrytype.cpp index ad1ee4feda..ebe28c4067 100644 --- a/src/script/api/script_industrytype.cpp +++ b/src/script/api/script_industrytype.cpp @@ -15,6 +15,7 @@ #include "../../industry.h" #include "../../newgrf_industries.h" #include "../../core/random_func.hpp" +#include "../../industry_cmd.h" #include "../../safeguards.h" @@ -122,7 +123,7 @@ uint32 seed = ::InteractiveRandom(); uint32 layout_index = ::InteractiveRandomRange((uint32)::GetIndustrySpec(industry_type)->layouts.size()); - return ScriptObject::DoCommand(tile, (1 << 16) | (layout_index << 8) | industry_type, seed, CMD_BUILD_INDUSTRY); + return ScriptObject::Command::Do(tile, (1 << 16) | (layout_index << 8) | industry_type, seed, {}); } /* static */ bool ScriptIndustryType::ProspectIndustry(IndustryType industry_type) @@ -130,7 +131,7 @@ EnforcePrecondition(false, CanProspectIndustry(industry_type)); uint32 seed = ::InteractiveRandom(); - return ScriptObject::DoCommand(0, industry_type, seed, CMD_BUILD_INDUSTRY); + return ScriptObject::Command::Do(0, industry_type, seed, {}); } /* static */ bool ScriptIndustryType::IsBuiltOnWater(IndustryType industry_type) diff --git a/src/script/api/script_marine.cpp b/src/script/api/script_marine.cpp index 16f0228dbe..f368ec9185 100644 --- a/src/script/api/script_marine.cpp +++ b/src/script/api/script_marine.cpp @@ -11,7 +11,12 @@ #include "script_marine.hpp" #include "script_station.hpp" #include "../../station_base.h" +#include "../../dock_cmd.h" +#include "../../landscape_cmd.h" +#include "../../station_cmd.h" #include "../../tile_cmd.h" +#include "../../water_cmd.h" +#include "../../waypoint_cmd.h" #include "../../safeguards.h" @@ -78,7 +83,7 @@ EnforcePrecondition(false, ::IsValidTile(front)); EnforcePrecondition(false, (::TileX(front) == ::TileX(tile)) != (::TileY(front) == ::TileY(tile))); - return ScriptObject::DoCommand(tile, ::TileX(front) == ::TileX(tile), 0, CMD_BUILD_SHIP_DEPOT); + return ScriptObject::Command::Do(tile, ::TileX(front) == ::TileX(tile), 0, {}); } /* static */ bool ScriptMarine::BuildDock(TileIndex tile, StationID station_id) @@ -89,7 +94,7 @@ uint p1 = station_id == ScriptStation::STATION_JOIN_ADJACENT ? 0 : 1; uint p2 = (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; - return ScriptObject::DoCommand(tile, p1, p2, CMD_BUILD_DOCK); + return ScriptObject::Command::Do(tile, p1, p2, {}); } /* static */ bool ScriptMarine::BuildBuoy(TileIndex tile) @@ -97,7 +102,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_BUILD_BUOY); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ bool ScriptMarine::BuildLock(TileIndex tile) @@ -105,7 +110,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_BUILD_LOCK); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ bool ScriptMarine::BuildCanal(TileIndex tile) @@ -113,7 +118,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::DoCommand(tile, tile, WATER_CLASS_CANAL, CMD_BUILD_CANAL); + return ScriptObject::Command::Do(tile, tile, WATER_CLASS_CANAL, {}); } /* static */ bool ScriptMarine::RemoveWaterDepot(TileIndex tile) @@ -122,7 +127,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsWaterDepotTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ bool ScriptMarine::RemoveDock(TileIndex tile) @@ -131,7 +136,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsDockTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ bool ScriptMarine::RemoveBuoy(TileIndex tile) @@ -140,7 +145,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsBuoyTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ bool ScriptMarine::RemoveLock(TileIndex tile) @@ -149,7 +154,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsLockTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ bool ScriptMarine::RemoveCanal(TileIndex tile) @@ -158,7 +163,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsCanalTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ Money ScriptMarine::GetBuildCost(BuildType build_type) diff --git a/src/script/api/script_news.cpp b/src/script/api/script_news.cpp index 678cc69852..7f46f5aa6c 100644 --- a/src/script/api/script_news.cpp +++ b/src/script/api/script_news.cpp @@ -16,6 +16,7 @@ #include "script_error.hpp" #include "../../command_type.h" #include "../../string_func.h" +#include "../../news_cmd.h" #include "../../safeguards.h" @@ -38,5 +39,5 @@ if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; if (ref_type == NR_NONE) reference = 0; - return ScriptObject::DoCommand(0, type | (ref_type << 8) | (c << 16), reference, CMD_CUSTOM_NEWS_ITEM, encoded); + return ScriptObject::Command::Do(0, type | (ref_type << 8) | (c << 16), reference, encoded); } diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index c63d2a2ea8..de4fab481b 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -296,39 +296,35 @@ ScriptObject::ActiveInstance::~ActiveInstance() return GetStorage()->callback_value[index]; } -/* static */ bool ScriptObject::DoCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd, const char *text, Script_SuspendCallbackProc *callback) +/* static */ CommandCallback *ScriptObject::GetDoCommandCallback() +{ + return ScriptObject::GetActiveInstance()->GetDoCommandCallback(); +} + +std::tuple ScriptObject::DoCommandPrep() { if (!ScriptObject::CanSuspend()) { throw Script_FatalError("You are not allowed to execute any DoCommand (even indirect) in your constructor, Save(), Load(), and any valuator."); } + /* Are we only interested in the estimate costs? */ + bool estimate_only = GetDoCommandMode() != nullptr && !GetDoCommandMode()(); + + bool networking = _networking && !_generating_world; + if (ScriptObject::GetCompany() != OWNER_DEITY && !::Company::IsValidID(ScriptObject::GetCompany())) { ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); - return false; + return { true, estimate_only, networking }; } - std::string command_text = text == nullptr ? std::string{} : text; - if (!command_text.empty() && (GetCommandFlags(cmd) & CMD_STR_CTRL) == 0) { - /* The string must be valid, i.e. not contain special codes. Since some - * can be made with GSText, make sure the control codes are removed. */ - command_text = ::StrMakeValid(command_text, SVS_NONE); - } + return { false, estimate_only, networking }; +} +bool ScriptObject::DoCommandProcessResult(const CommandCost &res, Script_SuspendCallbackProc *callback, bool estimate_only) +{ /* Set the default callback to return a true/false result of the DoCommand */ if (callback == nullptr) callback = &ScriptInstance::DoCommandReturn; - /* Are we only interested in the estimate costs? */ - bool estimate_only = GetDoCommandMode() != nullptr && !GetDoCommandMode()(); - - /* Only set p2 when the command does not come from the network. */ - if (GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = UINT32_MAX; - - /* Store the command for command callback validation. */ - if (!estimate_only && _networking && !_generating_world) SetLastCommand(tile, EndianBufferWriter::FromValue(std::make_tuple(tile, p1, p2, command_text)), cmd); - - /* Try to perform the command. */ - CommandCost res = ::DoCommandPInternal(cmd, STR_NULL, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, false, estimate_only, false, tile, p1, p2, command_text); - /* We failed; set the error and bail out */ if (res.Failed()) { SetLastError(ScriptError::StringToError(res.GetErrorMessage())); diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index 40c8eaf854..cfb6d393a4 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -13,7 +13,8 @@ #include "../../misc/countedptr.hpp" #include "../../road_type.h" #include "../../rail_type.h" -#include "../../command_type.h" +#include "../../string_func.h" +#include "../../command_func.h" #include "script_types.hpp" #include "../script_suspend.hpp" @@ -67,10 +68,32 @@ public: static class ScriptInstance *GetActiveInstance(); protected: + template struct ScriptDoCommandHelper; + /** - * Executes a raw DoCommand for the script. + * Templated wrapper that exposes the command parameter arguments + * on the various DoCommand calls. + * @tparam Tcmd The command-id to execute. + * @tparam Targs The command parameter types. */ - static bool DoCommand(TileIndex tile, uint32 p1, uint32 p2, Commands cmd, const char *text = nullptr, Script_SuspendCallbackProc *callback = nullptr); + template + struct ScriptDoCommandHelper { + static bool Do(Script_SuspendCallbackProc *callback, Targs... args) + { + return Execute(callback, std::forward_as_tuple(args...)); + } + + static bool Do(Targs... args) + { + return Execute(nullptr, std::forward_as_tuple(args...)); + } + + private: + static bool Execute(Script_SuspendCallbackProc *callback, std::tuple args); + }; + + template + using Command = ScriptDoCommandHelper::ProcType>; /** * Store the latest command executed by the script. @@ -299,6 +322,58 @@ private: * @param story_page_id The new StoryPageID. */ static void SetNewStoryPageElementID(StoryPageElementID story_page_element_id); + + /* Helper functions for DoCommand. */ + static std::tuple DoCommandPrep(); + static bool DoCommandProcessResult(const CommandCost &res, Script_SuspendCallbackProc *callback, bool estimate_only); + static CommandCallback *GetDoCommandCallback(); }; +namespace ScriptObjectInternal { + /** Validate a single string argument coming from network. */ + template + static inline void SanitizeSingleStringHelper(T &data) + { + if constexpr (std::is_same_v) { + /* The string must be valid, i.e. not contain special codes. Since some + * can be made with GSText, make sure the control codes are removed. */ + data = ::StrMakeValid(data, SVS_NONE); + } + } + + /** Helper function to perform validation on command data strings. */ + template + static inline void SanitizeStringsHelper(Ttuple &values, std::index_sequence) + { + ((SanitizeSingleStringHelper(std::get(values))), ...); + } +} + +template +bool ScriptObject::ScriptDoCommandHelper::Execute(Script_SuspendCallbackProc *callback, std::tuple args) +{ + auto [err, estimate_only, networking] = ScriptObject::DoCommandPrep(); + if (err) return false; + + if ((::GetCommandFlags() & CMD_STR_CTRL) == 0) { + ScriptObjectInternal::SanitizeStringsHelper(args, std::index_sequence_for{}); + } + + TileIndex tile{}; + if constexpr (std::is_same_v>) { + tile = std::get<0>(args); + } + + /* Only set p2 when the command does not come from the network. */ + if ((::GetCommandFlags() & CMD_CLIENT_ID) != 0 && std::get<2>(args) == 0) std::get<2>(args) = UINT32_MAX; + + /* Store the command for command callback validation. */ + if (!estimate_only && networking) ScriptObject::SetLastCommand(tile, EndianBufferWriter::FromValue(args), Tcmd); + + /* Try to perform the command. */ + CommandCost res = std::apply(&DoCommandPInternal, std::tuple_cat(std::make_tuple(Tcmd, (StringID)0, networking ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, false), args)); + + return ScriptObject::DoCommandProcessResult(res, callback, estimate_only); +} + #endif /* SCRIPT_OBJECT_HPP */ diff --git a/src/script/api/script_objecttype.cpp b/src/script/api/script_objecttype.cpp index 27519a664f..a4a8ef9843 100644 --- a/src/script/api/script_objecttype.cpp +++ b/src/script/api/script_objecttype.cpp @@ -13,6 +13,7 @@ #include "script_error.hpp" #include "script_map.hpp" +#include "../../object_cmd.h" #include "../../safeguards.h" @@ -41,5 +42,5 @@ EnforcePrecondition(false, IsValidObjectType(object_type)); EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); - return ScriptObject::DoCommand(tile, object_type, view, CMD_BUILD_OBJECT); + return ScriptObject::Command::Do(tile, object_type, view, {}); } diff --git a/src/script/api/script_order.cpp b/src/script/api/script_order.cpp index ce0ee76dee..8faec672f0 100644 --- a/src/script/api/script_order.cpp +++ b/src/script/api/script_order.cpp @@ -18,6 +18,7 @@ #include "../../depot_base.h" #include "../../station_base.h" #include "../../waypoint_base.h" +#include "../../order_cmd.h" #include "../../safeguards.h" @@ -379,7 +380,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position)); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to) && jump_to != ORDER_CURRENT); - return ScriptObject::DoCommand(0, vehicle_id | (order_position << 20), MOF_COND_DESTINATION | (jump_to << 4), CMD_MODIFY_ORDER); + return ScriptObject::Command::Do(0, vehicle_id | (order_position << 20), MOF_COND_DESTINATION | (jump_to << 4), {}); } /* static */ bool ScriptOrder::SetOrderCondition(VehicleID vehicle_id, OrderPosition order_position, OrderCondition condition) @@ -389,7 +390,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, condition >= OC_LOAD_PERCENTAGE && condition <= OC_REMAINING_LIFETIME); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), MOF_COND_VARIABLE | (condition << 4), CMD_MODIFY_ORDER); + return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), MOF_COND_VARIABLE | (condition << 4), {}); } /* static */ bool ScriptOrder::SetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position, CompareFunction compare) @@ -399,7 +400,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, compare >= CF_EQUALS && compare <= CF_IS_FALSE); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), MOF_COND_COMPARATOR | (compare << 4), CMD_MODIFY_ORDER); + return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), MOF_COND_COMPARATOR | (compare << 4), {}); } /* static */ bool ScriptOrder::SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, int32 value) @@ -410,7 +411,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (GetOrderCondition(vehicle_id, order_position) == OC_MAX_SPEED) value = value * 10 / 16; int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), MOF_COND_VALUE | (value << 4), CMD_MODIFY_ORDER); + return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), MOF_COND_VALUE | (value << 4), {}); } /* static */ bool ScriptOrder::SetStopLocation(VehicleID vehicle_id, OrderPosition order_position, StopLocation stop_location) @@ -425,7 +426,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); uint32 p1 = vehicle_id | (order_pos << 20); uint32 p2 = MOF_STOP_LOCATION | (stop_location << 4); - return ScriptObject::DoCommand(0, p1, p2, CMD_MODIFY_ORDER); + return ScriptObject::Command::Do(0, p1, p2, {}); } /* static */ bool ScriptOrder::SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoID refit_cargo) @@ -436,7 +437,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr uint32 p1 = vehicle_id; uint32 p2 = refit_cargo | ScriptOrderPositionToRealOrderPosition(vehicle_id, ScriptOrder::ResolveOrderPosition(vehicle_id, order_position)) << 16; - return ScriptObject::DoCommand(0, p1, p2, CMD_ORDER_REFIT); + return ScriptObject::Command::Do(0, p1, p2, {}); } /* static */ bool ScriptOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, ScriptOrderFlags order_flags) @@ -506,7 +507,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr order.SetNonStopType((OrderNonStopFlags)GB(order_flags, 0, 2)); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), order.Pack(), CMD_INSERT_ORDER); + return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), order.Pack(), {}); } /* static */ bool ScriptOrder::InsertConditionalOrder(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to) @@ -522,7 +523,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr order.MakeConditional(jump_to); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), order.Pack(), CMD_INSERT_ORDER); + return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), order.Pack(), {}); } /* static */ bool ScriptOrder::RemoveOrder(VehicleID vehicle_id, OrderPosition order_position) @@ -532,7 +533,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::DoCommand(0, vehicle_id, order_pos, CMD_DELETE_ORDER); + return ScriptObject::Command::Do(0, vehicle_id, order_pos, {}); } /* static */ bool ScriptOrder::SkipToOrder(VehicleID vehicle_id, OrderPosition next_order) @@ -542,7 +543,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, next_order)); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, next_order); - return ScriptObject::DoCommand(0, vehicle_id, order_pos, CMD_SKIP_TO_ORDER); + return ScriptObject::Command::Do(0, vehicle_id, order_pos, {}); } /** @@ -586,7 +587,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) EnforcePrecondition(false, (order_flags & OF_GOTO_NEAREST_DEPOT) == (current & OF_GOTO_NEAREST_DEPOT)); if ((current & OF_NON_STOP_FLAGS) != (order_flags & OF_NON_STOP_FLAGS)) { - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (order_flags & OF_NON_STOP_FLAGS) << 4 | MOF_NON_STOP, CMD_MODIFY_ORDER, nullptr, &::_DoCommandReturnSetOrderFlags); + return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, 0, vehicle_id | (order_pos << 20), (order_flags & OF_NON_STOP_FLAGS) << 4 | MOF_NON_STOP, {}); } switch (order->GetType()) { @@ -595,16 +596,16 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) uint data = DA_ALWAYS_GO; if (order_flags & OF_SERVICE_IF_NEEDED) data = DA_SERVICE; if (order_flags & OF_STOP_IN_DEPOT) data = DA_STOP; - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (data << 4) | MOF_DEPOT_ACTION, CMD_MODIFY_ORDER, nullptr, &::_DoCommandReturnSetOrderFlags); + return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, 0, vehicle_id | (order_pos << 20), (data << 4) | MOF_DEPOT_ACTION, {}); } break; case OT_GOTO_STATION: if ((current & OF_UNLOAD_FLAGS) != (order_flags & OF_UNLOAD_FLAGS)) { - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (order_flags & OF_UNLOAD_FLAGS) << 2 | MOF_UNLOAD, CMD_MODIFY_ORDER, nullptr, &::_DoCommandReturnSetOrderFlags); + return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, 0, vehicle_id | (order_pos << 20), (order_flags & OF_UNLOAD_FLAGS) << 2 | MOF_UNLOAD, {}); } if ((current & OF_LOAD_FLAGS) != (order_flags & OF_LOAD_FLAGS)) { - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (order_flags & OF_LOAD_FLAGS) >> 1 | MOF_LOAD, CMD_MODIFY_ORDER, nullptr, &::_DoCommandReturnSetOrderFlags); + return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, 0, vehicle_id | (order_pos << 20), (order_flags & OF_LOAD_FLAGS) >> 1 | MOF_LOAD, {}); } break; @@ -638,7 +639,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) int order_pos_move = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position_move); int order_pos_target = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position_target); - return ScriptObject::DoCommand(0, vehicle_id, order_pos_move | (order_pos_target << 16), CMD_MOVE_ORDER); + return ScriptObject::Command::Do(0, vehicle_id, order_pos_move | (order_pos_target << 16), {}); } /* static */ bool ScriptOrder::CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id) @@ -646,7 +647,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(main_vehicle_id)); - return ScriptObject::DoCommand(0, vehicle_id | CO_COPY << 30, main_vehicle_id, CMD_CLONE_ORDER); + return ScriptObject::Command::Do(0, vehicle_id | CO_COPY << 30, main_vehicle_id, {}); } /* static */ bool ScriptOrder::ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id) @@ -654,14 +655,14 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(main_vehicle_id)); - return ScriptObject::DoCommand(0, vehicle_id | CO_SHARE << 30, main_vehicle_id, CMD_CLONE_ORDER); + return ScriptObject::Command::Do(0, vehicle_id | CO_SHARE << 30, main_vehicle_id, {}); } /* static */ bool ScriptOrder::UnshareOrders(VehicleID vehicle_id) { EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); - return ScriptObject::DoCommand(0, vehicle_id | CO_UNSHARE << 30, 0, CMD_CLONE_ORDER); + return ScriptObject::Command::Do(0, vehicle_id | CO_UNSHARE << 30, 0, {}); } /* static */ uint ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile) diff --git a/src/script/api/script_rail.cpp b/src/script/api/script_rail.cpp index 8668906c28..ebba16343c 100644 --- a/src/script/api/script_rail.cpp +++ b/src/script/api/script_rail.cpp @@ -18,6 +18,9 @@ #include "../../newgrf_generic.h" #include "../../newgrf_station.h" #include "../../strings_func.h" +#include "../../rail_cmd.h" +#include "../../station_cmd.h" +#include "../../waypoint_cmd.h" #include "../../safeguards.h" @@ -113,7 +116,7 @@ EnforcePrecondition(false, ::IsValidTile(end_tile)); EnforcePrecondition(false, IsRailTypeAvailable(convert_to)); - return ScriptObject::DoCommand(start_tile, end_tile, convert_to, CMD_CONVERT_RAIL); + return ScriptObject::Command::Do(start_tile, end_tile, convert_to, {}); } /* static */ TileIndex ScriptRail::GetRailDepotFrontTile(TileIndex depot) @@ -141,7 +144,7 @@ uint entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0); - return ScriptObject::DoCommand(tile, ScriptObject::GetRailType(), entrance_dir, CMD_BUILD_TRAIN_DEPOT); + return ScriptObject::Command::Do(tile, ScriptObject::GetRailType(), entrance_dir, {}); } /* static */ bool ScriptRail::BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id) @@ -157,7 +160,7 @@ uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8); if (direction == RAILTRACK_NW_SE) p1 |= (1 << 6); if (station_id != ScriptStation::STATION_JOIN_ADJACENT) p1 |= (1 << 24); - return ScriptObject::DoCommand(tile, p1, (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16, CMD_BUILD_RAIL_STATION); + return ScriptObject::Command::Do(tile, p1, (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16, {}); } /* static */ bool ScriptRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station) @@ -198,11 +201,11 @@ Debug(grf, 1, "{} returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename); } else { /* We might have gotten an usable station spec. Try to build it, but if it fails we'll fall back to the original station. */ - if (ScriptObject::DoCommand(tile, p1, p2 | spec->cls_id | index << 8, CMD_BUILD_RAIL_STATION)) return true; + if (ScriptObject::Command::Do(tile, p1, p2 | spec->cls_id | index << 8, {})) return true; } } - return ScriptObject::DoCommand(tile, p1, p2, CMD_BUILD_RAIL_STATION); + return ScriptObject::Command::Do(tile, p1, p2, {}); } /* static */ bool ScriptRail::BuildRailWaypoint(TileIndex tile) @@ -213,7 +216,7 @@ EnforcePrecondition(false, GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); - return ScriptObject::DoCommand(tile, GetCurrentRailType() | (GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y) << 6 | 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, CMD_BUILD_RAIL_WAYPOINT); + return ScriptObject::Command::Do(tile, GetCurrentRailType() | (GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y) << 6 | 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, {}); } /* static */ bool ScriptRail::RemoveRailWaypointTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail) @@ -222,7 +225,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(tile2)); - return ScriptObject::DoCommand(tile, tile2, keep_rail ? 1 : 0, CMD_REMOVE_FROM_RAIL_WAYPOINT); + return ScriptObject::Command::Do(tile, tile2, keep_rail ? 1 : 0, {}); } /* static */ bool ScriptRail::RemoveRailStationTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail) @@ -231,7 +234,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(tile2)); - return ScriptObject::DoCommand(tile, tile2, keep_rail ? 1 : 0, CMD_REMOVE_FROM_RAIL_STATION); + return ScriptObject::Command::Do(tile, tile2, keep_rail ? 1 : 0, {}); } /* static */ uint ScriptRail::GetRailTracks(TileIndex tile) @@ -253,7 +256,7 @@ EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); - return ScriptObject::DoCommand(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 6), CMD_BUILD_RAILROAD_TRACK); + return ScriptObject::Command::Do(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 6), {}); } /* static */ bool ScriptRail::RemoveRailTrack(TileIndex tile, RailTrack rail_track) @@ -264,7 +267,7 @@ EnforcePrecondition(false, GetRailTracks(tile) & rail_track); EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0); - return ScriptObject::DoCommand(tile, tile, FindFirstTrack((::TrackBits)rail_track) << 6, CMD_REMOVE_RAILROAD_TRACK); + return ScriptObject::Command::Do(tile, tile, FindFirstTrack((::TrackBits)rail_track) << 6, {}); } /* static */ bool ScriptRail::AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to) @@ -365,7 +368,7 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) (::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to))); uint32 p2 = SimulateDrag(from, tile, &to) | 1 << 10 | ScriptRail::GetCurrentRailType();; - return ScriptObject::DoCommand(tile, to, p2, CMD_BUILD_RAILROAD_TRACK); + return ScriptObject::Command::Do(tile, to, p2, {}); } /* static */ bool ScriptRail::RemoveRail(TileIndex from, TileIndex tile, TileIndex to) @@ -382,7 +385,7 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) (::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to))); uint32 p2 = SimulateDrag(from, tile, &to); - return ScriptObject::DoCommand(tile, to, p2, CMD_REMOVE_RAILROAD_TRACK); + return ScriptObject::Command::Do(tile, to, p2, {}); } /** @@ -468,7 +471,7 @@ static bool IsValidSignalType(int signal_type) } p1 |= ((signal >= SIGNALTYPE_TWOWAY ? signal ^ SIGNALTYPE_TWOWAY : signal) << 5); - return ScriptObject::DoCommand(tile, p1, 0, CMD_BUILD_SIGNALS); + return ScriptObject::Command::Do(tile, p1, 0, {}); } /* static */ bool ScriptRail::RemoveSignal(TileIndex tile, TileIndex front) @@ -487,7 +490,7 @@ static bool IsValidSignalType(int signal_type) } EnforcePrecondition(false, track != INVALID_TRACK); - return ScriptObject::DoCommand(tile, track, 0, CMD_REMOVE_SIGNALS); + return ScriptObject::Command::Do(tile, track, 0, {}); } /* static */ Money ScriptRail::GetBuildCost(RailType railtype, BuildType build_type) diff --git a/src/script/api/script_road.cpp b/src/script/api/script_road.cpp index e1549b0d77..26cdb5190a 100644 --- a/src/script/api/script_road.cpp +++ b/src/script/api/script_road.cpp @@ -12,6 +12,9 @@ #include "script_station.hpp" #include "script_cargo.hpp" #include "../../station_base.h" +#include "../../landscape_cmd.h" +#include "../../road_cmd.h" +#include "../../station_cmd.h" #include "../../script/squirrel_helper_type.hpp" #include "../../safeguards.h" @@ -126,7 +129,7 @@ EnforcePrecondition(false, ::IsValidTile(end_tile)); EnforcePrecondition(false, IsRoadTypeAvailable(road_type)); - return ScriptObject::DoCommand(start_tile, end_tile, (::RoadType)road_type, CMD_CONVERT_ROAD); + return ScriptObject::Command::Do(start_tile, end_tile, (::RoadType)road_type, {}); } /* Helper functions for ScriptRoad::CanBuildConnectedRoadParts(). */ @@ -492,7 +495,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, !one_way || RoadTypeIsRoad(ScriptObject::GetRoadType())); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - return ScriptObject::DoCommand(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (((start < end) == !full) ? 1 : 2) | (ScriptObject::GetRoadType() << 3) | ((one_way ? 1 : 0) << 10) | 1 << 11, CMD_BUILD_LONG_ROAD); + return ScriptObject::Command::Do(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (((start < end) == !full) ? 1 : 2) | (ScriptObject::GetRoadType() << 3) | ((one_way ? 1 : 0) << 10) | 1 << 11, {}); } /* static */ bool ScriptRoad::BuildRoad(TileIndex start, TileIndex end) @@ -528,7 +531,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD uint entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0); - return ScriptObject::DoCommand(tile, entrance_dir | (ScriptObject::GetRoadType() << 2), 0, CMD_BUILD_ROAD_DEPOT); + return ScriptObject::Command::Do(tile, entrance_dir | (ScriptObject::GetRoadType() << 2), 0, {}); } /* static */ bool ScriptRoad::_BuildRoadStationInternal(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, bool drive_through, StationID station_id) @@ -555,7 +558,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD p2 |= ScriptObject::GetRoadType() << 5; p2 |= entrance_dir << 3; p2 |= (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; - return ScriptObject::DoCommand(tile, 1 | 1 << 8, p2, CMD_BUILD_ROAD_STOP); + return ScriptObject::Command::Do(tile, 1 | 1 << 8, p2, {}); } /* static */ bool ScriptRoad::BuildRoadStation(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, StationID station_id) @@ -577,7 +580,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end)); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - return ScriptObject::DoCommand(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 1 : 2) | (ScriptObject::GetRoadType() << 3), CMD_REMOVE_LONG_ROAD); + return ScriptObject::Command::Do(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 1 : 2) | (ScriptObject::GetRoadType() << 3), {}); } /* static */ bool ScriptRoad::RemoveRoadFull(TileIndex start, TileIndex end) @@ -589,7 +592,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end)); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - return ScriptObject::DoCommand(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 2 : 1) | (ScriptObject::GetRoadType() << 3), CMD_REMOVE_LONG_ROAD); + return ScriptObject::Command::Do(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 2 : 1) | (ScriptObject::GetRoadType() << 3), {}); } /* static */ bool ScriptRoad::RemoveRoadDepot(TileIndex tile) @@ -599,7 +602,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, IsTileType(tile, MP_ROAD)) EnforcePrecondition(false, GetRoadTileType(tile) == ROAD_TILE_DEPOT); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ bool ScriptRoad::RemoveRoadStation(TileIndex tile) @@ -609,7 +612,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, IsTileType(tile, MP_STATION)); EnforcePrecondition(false, IsRoadStop(tile)); - return ScriptObject::DoCommand(tile, 1 | 1 << 8, GetRoadStopType(tile), CMD_REMOVE_ROAD_STOP); + return ScriptObject::Command::Do(tile, 1 | 1 << 8, GetRoadStopType(tile), {}); } /* static */ Money ScriptRoad::GetBuildCost(RoadType roadtype, BuildType build_type) diff --git a/src/script/api/script_sign.cpp b/src/script/api/script_sign.cpp index 8908941cf7..6062497f0c 100644 --- a/src/script/api/script_sign.cpp +++ b/src/script/api/script_sign.cpp @@ -15,6 +15,7 @@ #include "../../string_func.h" #include "../../strings_func.h" #include "../../tile_map.h" +#include "../../signs_cmd.h" #include "../../safeguards.h" @@ -41,7 +42,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::DoCommand(0, sign_id, 0, CMD_RENAME_SIGN, text); + return ScriptObject::Command::Do(0, sign_id, 0, text); } /* static */ char *ScriptSign::GetName(SignID sign_id) @@ -63,7 +64,7 @@ /* static */ bool ScriptSign::RemoveSign(SignID sign_id) { EnforcePrecondition(false, IsValidSign(sign_id)); - return ScriptObject::DoCommand(0, sign_id, 0, CMD_RENAME_SIGN, ""); + return ScriptObject::Command::Do(0, sign_id, 0, ""); } /* static */ SignID ScriptSign::BuildSign(TileIndex location, Text *name) @@ -76,7 +77,7 @@ EnforcePreconditionEncodedText(INVALID_SIGN, text); EnforcePreconditionCustomError(INVALID_SIGN, ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - if (!ScriptObject::DoCommand(location, 0, 0, CMD_PLACE_SIGN, text, &ScriptInstance::DoCommandReturnSignID)) return INVALID_SIGN; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnSignID, location, 0, 0, text)) return INVALID_SIGN; /* In case of test-mode, we return SignID 0 */ return 0; diff --git a/src/script/api/script_station.cpp b/src/script/api/script_station.cpp index a45c19d0d9..34e7d84341 100644 --- a/src/script/api/script_station.cpp +++ b/src/script/api/script_station.cpp @@ -15,6 +15,7 @@ #include "../../station_base.h" #include "../../roadstop_base.h" #include "../../town.h" +#include "../../station_cmd.h" #include "../../safeguards.h" @@ -239,5 +240,5 @@ template EnforcePrecondition(false, IsValidStation(station_id)); EnforcePrecondition(false, HasStationType(station_id, STATION_AIRPORT)); - return ScriptObject::DoCommand(0, station_id, 0, CMD_OPEN_CLOSE_AIRPORT); + return ScriptObject::Command::Do(0, station_id, 0, {}); } diff --git a/src/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp index 4ee90e218d..afa2590414 100644 --- a/src/script/api/script_story_page.cpp +++ b/src/script/api/script_story_page.cpp @@ -19,6 +19,7 @@ #include "../../goal_base.h" #include "../../string_func.h" #include "../../tile_map.h" +#include "../../story_cmd.h" #include "../../safeguards.h" @@ -47,12 +48,11 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) uint8 c = company; if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; - if (!ScriptObject::DoCommand(0, + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnStoryPageID, + 0, c, 0, - CMD_CREATE_STORY_PAGE, - title != nullptr? title->GetEncodedText() : nullptr, - &ScriptInstance::DoCommandReturnStoryPageID)) return STORY_PAGE_INVALID; + title != nullptr ? std::string{ title->GetEncodedText() } : std::string{})) return STORY_PAGE_INVALID; /* In case of test-mode, we return StoryPageID 0 */ return (ScriptStoryPage::StoryPageID)0; @@ -89,12 +89,11 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) NOT_REACHED(); } - if (!ScriptObject::DoCommand(reftile, + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnStoryPageElementID, + reftile, story_page_id + (type << 16), refid, - CMD_CREATE_STORY_PAGE_ELEMENT, - StoryPageElementTypeRequiresText(btype) ? text->GetEncodedText() : nullptr, - &ScriptInstance::DoCommandReturnStoryPageElementID)) return STORY_PAGE_ELEMENT_INVALID; + StoryPageElementTypeRequiresText(btype) ? std::string{ text->GetEncodedText() } : std::string{})) return STORY_PAGE_ELEMENT_INVALID; /* In case of test-mode, we return StoryPageElementID 0 */ return (ScriptStoryPage::StoryPageElementID)0; @@ -134,11 +133,10 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) NOT_REACHED(); } - return ScriptObject::DoCommand(reftile, + return ScriptObject::Command::Do(reftile, story_page_element_id, refid, - CMD_UPDATE_STORY_PAGE_ELEMENT, - StoryPageElementTypeRequiresText(type) ? text->GetEncodedText() : nullptr); + StoryPageElementTypeRequiresText(type) ? std::string{ text->GetEncodedText() } : std::string{}); } /* static */ uint32 ScriptStoryPage::GetPageSortValue(StoryPageID story_page_id) @@ -162,7 +160,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, IsValidStoryPage(story_page_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::DoCommand(0, story_page_id, 0, CMD_SET_STORY_PAGE_TITLE, title != nullptr? title->GetEncodedText() : nullptr); + return ScriptObject::Command::Do(0, story_page_id, 0, title != nullptr ? std::string{ title->GetEncodedText() } : std::string{}); } /* static */ ScriptCompany::CompanyID ScriptStoryPage::GetCompany(StoryPageID story_page_id) @@ -188,7 +186,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, IsValidStoryPage(story_page_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::DoCommand(0, story_page_id, date, CMD_SET_STORY_PAGE_DATE, nullptr); + return ScriptObject::Command::Do(0, story_page_id, date, {}); } @@ -197,7 +195,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, IsValidStoryPage(story_page_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::DoCommand(0, story_page_id, 0, CMD_SHOW_STORY_PAGE); + return ScriptObject::Command::Do(0, story_page_id, 0, {}); } /* static */ bool ScriptStoryPage::Remove(StoryPageID story_page_id) @@ -205,7 +203,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); EnforcePrecondition(false, IsValidStoryPage(story_page_id)); - return ScriptObject::DoCommand(0, story_page_id, 0, CMD_REMOVE_STORY_PAGE); + return ScriptObject::Command::Do(0, story_page_id, 0, {}); } /* static */ bool ScriptStoryPage::RemoveElement(StoryPageElementID story_page_element_id) @@ -213,7 +211,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); EnforcePrecondition(false, IsValidStoryPageElement(story_page_element_id)); - return ScriptObject::DoCommand(0, story_page_element_id, 0, CMD_REMOVE_STORY_PAGE_ELEMENT); + return ScriptObject::Command::Do(0, story_page_element_id, 0, {}); } /* static */ ScriptStoryPage::StoryPageButtonFormatting ScriptStoryPage::MakePushButtonReference(StoryPageButtonColour colour, StoryPageButtonFlags flags) diff --git a/src/script/api/script_subsidy.cpp b/src/script/api/script_subsidy.cpp index c8ca6e3e35..32962d1581 100644 --- a/src/script/api/script_subsidy.cpp +++ b/src/script/api/script_subsidy.cpp @@ -15,6 +15,7 @@ #include "script_error.hpp" #include "../../subsidy_base.h" #include "../../station_base.h" +#include "../../subsidy_cmd.h" #include "../../safeguards.h" @@ -38,7 +39,7 @@ EnforcePrecondition(false, (from_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(from_id)) || (from_type == SPT_TOWN && ScriptTown::IsValidTown(from_id))); EnforcePrecondition(false, (to_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(to_id)) || (to_type == SPT_TOWN && ScriptTown::IsValidTown(to_id))); - return ScriptObject::DoCommand(0, from_type | (from_id << 8) | (cargo_type << 24), to_type | (to_id << 8), CMD_CREATE_SUBSIDY); + return ScriptObject::Command::Do(0, from_type | (from_id << 8) | (cargo_type << 24), to_type | (to_id << 8), {}); } /* static */ ScriptCompany::CompanyID ScriptSubsidy::GetAwardedTo(SubsidyID subsidy_id) diff --git a/src/script/api/script_tile.cpp b/src/script/api/script_tile.cpp index 90411a7f76..9e67b074a2 100644 --- a/src/script/api/script_tile.cpp +++ b/src/script/api/script_tile.cpp @@ -17,6 +17,9 @@ #include "../../tree_map.h" #include "../../town.h" #include "../../landscape.h" +#include "../../landscape_cmd.h" +#include "../../terraform_cmd.h" +#include "../../tree_cmd.h" #include "../../safeguards.h" @@ -252,7 +255,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, tile < ::MapSize()); - return ScriptObject::DoCommand(tile, slope, 1, CMD_TERRAFORM_LAND); + return ScriptObject::Command::Do(tile, slope, 1, {}); } /* static */ bool ScriptTile::LowerTile(TileIndex tile, int32 slope) @@ -260,7 +263,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, tile < ::MapSize()); - return ScriptObject::DoCommand(tile, slope, 0, CMD_TERRAFORM_LAND); + return ScriptObject::Command::Do(tile, slope, 0, {}); } /* static */ bool ScriptTile::LevelTiles(TileIndex start_tile, TileIndex end_tile) @@ -269,14 +272,14 @@ EnforcePrecondition(false, start_tile < ::MapSize()); EnforcePrecondition(false, end_tile < ::MapSize()); - return ScriptObject::DoCommand(end_tile, start_tile, LM_LEVEL << 1, CMD_LEVEL_LAND); + return ScriptObject::Command::Do(end_tile, start_tile, LM_LEVEL << 1, {}); } /* static */ bool ScriptTile::DemolishTile(TileIndex tile) { EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } /* static */ bool ScriptTile::PlantTree(TileIndex tile) @@ -284,7 +287,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::DoCommand(tile, TREE_INVALID, tile, CMD_PLANT_TREE); + return ScriptObject::Command::Do(tile, TREE_INVALID, tile, {}); } /* static */ bool ScriptTile::PlantTreeRectangle(TileIndex tile, uint width, uint height) @@ -295,7 +298,7 @@ EnforcePrecondition(false, height >= 1 && height <= 20); TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1); - return ScriptObject::DoCommand(tile, TREE_INVALID, end_tile, CMD_PLANT_TREE); + return ScriptObject::Command::Do(tile, TREE_INVALID, end_tile, {}); } /* static */ bool ScriptTile::IsWithinTownInfluence(TileIndex tile, TownID town_id) diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp index 161cf74fd8..e3fb26e893 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -17,6 +17,7 @@ #include "../../strings_func.h" #include "../../station_base.h" #include "../../landscape.h" +#include "../../town_cmd.h" #include "table/strings.h" #include "../../safeguards.h" @@ -51,7 +52,7 @@ } EnforcePrecondition(false, IsValidTown(town_id)); - return ScriptObject::DoCommand(0, town_id, 0, CMD_RENAME_TOWN, text); + return ScriptObject::Command::Do(0, town_id, 0, text != nullptr ? std::string{ text } : std::string{}); } /* static */ bool ScriptTown::SetText(TownID town_id, Text *text) @@ -65,7 +66,7 @@ } EnforcePrecondition(false, IsValidTown(town_id)); - return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, 0, CMD_TOWN_SET_TEXT, encoded_text); + return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id, 0, encoded_text != nullptr ? std::string{ encoded_text } : std::string{}); } /* static */ int32 ScriptTown::GetPopulation(TownID town_id) @@ -133,7 +134,7 @@ EnforcePrecondition(false, IsValidTown(town_id)); EnforcePrecondition(false, ScriptCargo::IsValidTownEffect(towneffect_id)); - return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id | (towneffect_id << 16), goal, CMD_TOWN_CARGO_GOAL); + return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id | (towneffect_id << 16), goal, {}); } /* static */ uint32 ScriptTown::GetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id) @@ -176,7 +177,7 @@ break; } - return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, growth_rate, CMD_TOWN_GROWTH_RATE); + return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id, growth_rate, {}); } /* static */ int32 ScriptTown::GetGrowthRate(TownID town_id) @@ -266,7 +267,7 @@ EnforcePrecondition(false, IsValidTown(town_id)); EnforcePrecondition(false, IsActionAvailable(town_id, town_action)); - return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, town_action, CMD_DO_TOWN_ACTION); + return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id, town_action, {}); } /* static */ bool ScriptTown::ExpandTown(TownID town_id, int houses) @@ -275,7 +276,7 @@ EnforcePrecondition(false, IsValidTown(town_id)); EnforcePrecondition(false, houses > 0); - return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, houses, CMD_EXPAND_TOWN); + return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id, houses, {}); } /* static */ bool ScriptTown::FoundTown(TileIndex tile, TownSize size, bool city, RoadLayout layout, Text *name) @@ -305,7 +306,7 @@ return false; } - return ScriptObject::DoCommand(tile, size | (city ? 1 << 2 : 0) | layout << 3, townnameparts, CMD_FOUND_TOWN, text); + return ScriptObject::Command::Do(tile, size | (city ? 1 << 2 : 0) | layout << 3, townnameparts, text != nullptr ? std::string{ text } : std::string{}); } /* static */ ScriptTown::TownRating ScriptTown::GetRating(TownID town_id, ScriptCompany::CompanyID company_id) @@ -360,7 +361,7 @@ uint16 p2 = 0; memcpy(&p2, &new_rating, sizeof(p2)); - return ScriptObject::DoCommand(0, town_id | (company_id << 16), p2, CMD_TOWN_RATING); + return ScriptObject::Command::Do(0, town_id | (company_id << 16), p2, {}); } /* static */ int ScriptTown::GetAllowedNoise(TownID town_id) diff --git a/src/script/api/script_tunnel.cpp b/src/script/api/script_tunnel.cpp index c47c64e40e..ea9cbc5186 100644 --- a/src/script/api/script_tunnel.cpp +++ b/src/script/api/script_tunnel.cpp @@ -12,6 +12,9 @@ #include "script_rail.hpp" #include "../script_instance.hpp" #include "../../tunnel_map.h" +#include "../../landscape_cmd.h" +#include "../../road_cmd.h" +#include "../../tunnelbridge_cmd.h" #include "../../safeguards.h" @@ -96,11 +99,11 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) /* For rail we do nothing special */ if (vehicle_type == ScriptVehicle::VT_RAIL) { - return ScriptObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL); + return ScriptObject::Command::Do(start, type, 0, {}); } ScriptObject::SetCallbackVariable(0, start); - return ScriptObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL, nullptr, &::_DoCommandReturnBuildTunnel1); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildTunnel1, start, type, 0, {}); } /* static */ bool ScriptTunnel::_BuildTunnelRoad1() @@ -112,7 +115,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, nullptr, &::_DoCommandReturnBuildTunnel2); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildTunnel2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptObject::GetRoadType() << 4), 0, {}); } /* static */ bool ScriptTunnel::_BuildTunnelRoad2() @@ -124,7 +127,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD); + return ScriptObject::Command::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptObject::GetRoadType() << 4), 0, {}); } /* static */ bool ScriptTunnel::RemoveTunnel(TileIndex tile) @@ -132,5 +135,5 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsTunnelTile(tile)); - return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); + return ScriptObject::Command::Do(tile, 0, 0, {}); } diff --git a/src/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp index a062616185..d245f41327 100644 --- a/src/script/api/script_vehicle.cpp +++ b/src/script/api/script_vehicle.cpp @@ -20,6 +20,8 @@ #include "../../train.h" #include "../../vehicle_func.h" #include "../../aircraft.h" +#include "../../roadveh_cmd.h" +#include "../../train_cmd.h" #include "../../vehicle_cmd.h" #include "table/strings.h" @@ -70,7 +72,7 @@ EnforcePreconditionCustomError(VEHICLE_INVALID, !ScriptGameSettings::IsDisabledVehicleType((ScriptVehicle::VehicleType)type), ScriptVehicle::ERR_VEHICLE_BUILD_DISABLED); - if (!ScriptObject::DoCommand(depot, engine_id | (cargo << 24), 0, CMD_BUILD_VEHICLE, nullptr, &ScriptInstance::DoCommandReturnVehicleID)) return VEHICLE_INVALID; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, engine_id | (cargo << 24), 0, {})) return VEHICLE_INVALID; /* In case of test-mode, we return VehicleID 0 */ return 0; @@ -101,7 +103,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - if (!ScriptObject::DoCommand(depot, vehicle_id, share_orders, CMD_CLONE_VEHICLE, nullptr, &ScriptInstance::DoCommandReturnVehicleID)) return VEHICLE_INVALID; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, vehicle_id, share_orders, {})) return VEHICLE_INVALID; /* In case of test-mode, we return VehicleID 0 */ return 0; @@ -123,7 +125,7 @@ while (dest_wagon-- > 0) w = w->GetNextUnit(); } - return ScriptObject::DoCommand(0, v->index | (move_attached_wagons ? 1 : 0) << 20, w == nullptr ? ::INVALID_VEHICLE : w->index, CMD_MOVE_RAIL_VEHICLE); + return ScriptObject::Command::Do(0, v->index | (move_attached_wagons ? 1 : 0) << 20, w == nullptr ? ::INVALID_VEHICLE : w->index, {}); } /* static */ bool ScriptVehicle::MoveWagon(VehicleID source_vehicle_id, int source_wagon, int dest_vehicle_id, int dest_wagon) @@ -150,7 +152,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id) && ScriptCargo::IsValidCargo(cargo)); - return ScriptObject::DoCommand(0, vehicle_id, cargo, CMD_REFIT_VEHICLE); + return ScriptObject::Command::Do(0, vehicle_id, cargo, {}); } @@ -160,7 +162,7 @@ EnforcePrecondition(false, IsValidVehicle(vehicle_id)); const Vehicle *v = ::Vehicle::Get(vehicle_id); - return ScriptObject::DoCommand(0, vehicle_id | (v->type == VEH_TRAIN ? 1 : 0) << 20, 0, CMD_SELL_VEHICLE); + return ScriptObject::Command::Do(0, vehicle_id | (v->type == VEH_TRAIN ? 1 : 0) << 20, 0, {}); } /* static */ bool ScriptVehicle::_SellWagonInternal(VehicleID vehicle_id, int wagon, bool sell_attached_wagons) @@ -172,7 +174,7 @@ const Train *v = ::Train::Get(vehicle_id); while (wagon-- > 0) v = v->GetNextUnit(); - return ScriptObject::DoCommand(0, v->index | (sell_attached_wagons ? 1 : 0) << 20, 0, CMD_SELL_VEHICLE); + return ScriptObject::Command::Do(0, v->index | (sell_attached_wagons ? 1 : 0) << 20, 0, {}); } /* static */ bool ScriptVehicle::SellWagon(VehicleID vehicle_id, int wagon) @@ -190,7 +192,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - return ScriptObject::DoCommand(0, vehicle_id, 0, CMD_SEND_VEHICLE_TO_DEPOT); + return ScriptObject::Command::Do(0, vehicle_id, 0, {}); } /* static */ bool ScriptVehicle::SendVehicleToDepotForServicing(VehicleID vehicle_id) @@ -198,7 +200,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - return ScriptObject::DoCommand(0, vehicle_id | DEPOT_SERVICE, 0, CMD_SEND_VEHICLE_TO_DEPOT); + return ScriptObject::Command::Do(0, vehicle_id | DEPOT_SERVICE, 0, {}); } /* static */ bool ScriptVehicle::IsInDepot(VehicleID vehicle_id) @@ -218,7 +220,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - return ScriptObject::DoCommand(0, vehicle_id, 0, CMD_START_STOP_VEHICLE); + return ScriptObject::Command::Do(0, vehicle_id, 0, {}); } /* static */ bool ScriptVehicle::ReverseVehicle(VehicleID vehicle_id) @@ -228,8 +230,8 @@ EnforcePrecondition(false, ::Vehicle::Get(vehicle_id)->type == VEH_ROAD || ::Vehicle::Get(vehicle_id)->type == VEH_TRAIN); switch (::Vehicle::Get(vehicle_id)->type) { - case VEH_ROAD: return ScriptObject::DoCommand(0, vehicle_id, 0, CMD_TURN_ROADVEH); - case VEH_TRAIN: return ScriptObject::DoCommand(0, vehicle_id, 0, CMD_REVERSE_TRAIN_DIRECTION); + case VEH_ROAD: return ScriptObject::Command::Do(0, vehicle_id, 0, {}); + case VEH_TRAIN: return ScriptObject::Command::Do(0, vehicle_id, 0, {}); default: NOT_REACHED(); } } @@ -245,7 +247,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_VEHICLE_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::DoCommand(0, vehicle_id, 0, CMD_RENAME_VEHICLE, text); + return ScriptObject::Command::Do(0, vehicle_id, 0, text); } /* static */ TileIndex ScriptVehicle::GetLocation(VehicleID vehicle_id) diff --git a/src/script/api/script_viewport.cpp b/src/script/api/script_viewport.cpp index 275ab33465..7d57bffb37 100644 --- a/src/script/api/script_viewport.cpp +++ b/src/script/api/script_viewport.cpp @@ -14,6 +14,7 @@ #include "script_map.hpp" #include "../script_instance.hpp" #include "../../viewport_func.h" +#include "../../viewport_cmd.h" #include "../../safeguards.h" @@ -30,7 +31,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); - return ScriptObject::DoCommand(tile, VST_EVERYONE, 0, CMD_SCROLL_VIEWPORT); + return ScriptObject::Command::Do(tile, VST_EVERYONE, 0, {}); } /* static */ bool ScriptViewport::ScrollCompanyClientsTo(ScriptCompany::CompanyID company, TileIndex tile) @@ -41,7 +42,7 @@ company = ScriptCompany::ResolveCompanyID(company); EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); - return ScriptObject::DoCommand(tile, VST_COMPANY, company, CMD_SCROLL_VIEWPORT); + return ScriptObject::Command::Do(tile, VST_COMPANY, company, {}); } /* static */ bool ScriptViewport::ScrollClientTo(ScriptClient::ClientID client, TileIndex tile) @@ -53,5 +54,5 @@ client = ScriptClient::ResolveClientID(client); EnforcePrecondition(false, client != ScriptClient::CLIENT_INVALID); - return ScriptObject::DoCommand(tile, VST_CLIENT, client, CMD_SCROLL_VIEWPORT); + return ScriptObject::Command::Do(tile, VST_CLIENT, client, {}); } From ccefa76a4686581b8d1a9bd13d7d754807a9f8d1 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Mon, 1 Nov 2021 23:07:27 +0100 Subject: [PATCH 19/60] Codechange: Template DoCommandPInternal. --- src/command.cpp | 138 +++++++++++++------------------ src/command_func.h | 96 ++++++++++++++++++++- src/network/network_client.cpp | 3 +- src/network/network_command.cpp | 16 ---- src/network/network_gui.cpp | 2 +- src/network/network_server.cpp | 2 +- src/order_backup.cpp | 2 +- src/script/api/script_object.hpp | 2 +- src/settings.cpp | 2 +- 9 files changed, 158 insertions(+), 105 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index dc536a843c..9997a66fec 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -274,53 +274,26 @@ void CommandHelperBase::InternalPostResult(const CommandCost &res, TileIndex til } } -/** Helper to format command parameters into a hex string. */ -static std::string CommandParametersToHexString(TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +/** Helper to make a desync log for a command. */ +void CommandHelperBase::LogCommandExecution(Commands cmd, StringID err_message, TileIndex tile, const CommandDataBuffer &args, bool failed) { - return FormatArrayAsHex(EndianBufferWriter<>::FromValue(std::make_tuple(tile, p1, p2, text))); + Debug(desync, 1, "{}: {:08x}; {:02x}; {:02x}; {:08x}; {:08x}; {:06x}; {} ({})", failed ? "cmdf" : "cmd", _date, _date_fract, (int)_current_company, cmd, err_message, tile, FormatArrayAsHex(args), GetCommandName(cmd)); } -/*! - * Helper function for the toplevel network safe docommand function for the current company. - * - * @param cmd The command to execute (a CMD_* value) - * @param err_message Message prefix to show on error - * @param callback A callback function to call after the command is finished - * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) - * @param estimate_only whether to give only the estimate or also execute the command - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - * @return the command cost of this function. +/** + * Prepare for the test run of a command proc call. + * @param cmd_flags Command flags. + * @param tile Tile of command execution. + * @param[in,out] cur_company Backup of current company at start of command execution. + * @return True if test run can go ahead, false on error. */ -CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +bool CommandHelperBase::InternalExecutePrepTest(CommandFlags cmd_flags, TileIndex tile, Backup &cur_company) { - RecursiveCommandCounter counter{}; - - /* Prevent recursion; it gives a mess over the network */ - assert(counter.IsTopLevel()); - /* Reset the state. */ _additional_cash_required = 0; - /* Get pointer to command handler */ - assert(cmd < _command_proc_table.size()); - CommandProc *proc = _command_proc_table[cmd].proc; - /* Shouldn't happen, but you never know when someone adds - * NULLs to the _command_proc_table. */ - assert(proc != nullptr); - - /* Command flags are used internally */ - CommandFlags cmd_flags = GetCommandFlags(cmd); - /* Flags get send to the DoCommand */ - DoCommandFlag flags = CommandFlagsToDCFlags(cmd_flags); - - /* Make sure p2 is properly set to a ClientID. */ - assert(!(cmd_flags & CMD_CLIENT_ID) || p2 != 0); - /* Do not even think about executing out-of-bounds tile-commands */ - if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (cmd_flags & CMD_ALL_TILES) == 0))) return CMD_ERROR; + if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (cmd_flags & CMD_ALL_TILES) == 0))) return false; /* Always execute server and spectator commands as spectator */ bool exec_as_spectator = (cmd_flags & (CMD_SPECTATOR | CMD_SERVER)) != 0; @@ -329,62 +302,68 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba * The server will ditch any server commands a client sends to it, so effectively * this guards the server from executing functions for an invalid company. */ if (_game_mode == GM_NORMAL && !exec_as_spectator && !Company::IsValidID(_current_company) && !(_current_company == OWNER_DEITY && (cmd_flags & CMD_DEITY) != 0)) { - return CMD_ERROR; + return false; } - Backup cur_company(_current_company, FILE_LINE); if (exec_as_spectator) cur_company.Change(COMPANY_SPECTATOR); - bool test_and_exec_can_differ = (cmd_flags & CMD_NO_TEST) != 0; - - /* Test the command. */ + /* Enter test mode. */ _cleared_object_areas.clear(); SetTownRatingTestMode(true); BasePersistentStorageArray::SwitchMode(PSM_ENTER_TESTMODE); - CommandCost res = proc(flags, tile, p1, p2, text); + return true; +} + +/** + * Validate result of test run and prepare for real execution. + * @param cmd_flags Command flags. + * @param[in,out] res Command result of test run, may be modified. + * @param estimate_only Is this just cost estimation? + * @param network_command Does this command come from the network? + * @param[in,out] cur_company Backup of current company at start of command execution. + * @return True if test run can go ahead, false on error. + */ +std::tuple CommandHelperBase::InternalExecuteValidateTestAndPrepExec(CommandCost &res, CommandFlags cmd_flags, bool estimate_only, bool network_command, Backup &cur_company) +{ BasePersistentStorageArray::SwitchMode(PSM_LEAVE_TESTMODE); SetTownRatingTestMode(false); /* Make sure we're not messing things up here. */ - assert(exec_as_spectator ? _current_company == COMPANY_SPECTATOR : cur_company.Verify()); + assert((cmd_flags & (CMD_SPECTATOR | CMD_SERVER)) != 0 ? _current_company == COMPANY_SPECTATOR : cur_company.Verify()); /* If the command fails, we're doing an estimate * or the player does not have enough money * (unless it's a command where the test and * execution phase might return different costs) * we bail out here. */ - if (res.Failed() || estimate_only || - (!test_and_exec_can_differ && !CheckCompanyHasMoney(res))) { - if (!_networking || _generating_world || network_command) { - /* Log the failed command as well. Just to be able to be find - * causes of desyncs due to bad command test implementations. */ - Debug(desync, 1, "cmdf: {:08x}; {:02x}; {:02x}; {:08x}; {:08x}; {:06x}; {} ({})", _date, _date_fract, (int)_current_company, cmd, err_message, tile, CommandParametersToHexString(tile, p1, p2, text), GetCommandName(cmd)); - } - cur_company.Restore(); - return res; + bool test_and_exec_can_differ = (cmd_flags & CMD_NO_TEST) != 0; + if (res.Failed() || estimate_only || (!test_and_exec_can_differ && !CheckCompanyHasMoney(res))) { + return { true, !_networking || _generating_world || network_command, false }; } - /* - * If we are in network, and the command is not from the network - * send it to the command-queue and abort execution - */ - if (_networking && !_generating_world && !network_command) { - NetworkSendCommand(cmd, err_message, callback, _current_company, tile, p1, p2, text); - cur_company.Restore(); + bool send_net = _networking && !_generating_world && !network_command; - /* Don't return anything special here; no error, no costs. - * This way it's not handled by DoCommand and only the - * actual execution of the command causes messages. Also - * reset the storages as we've not executed the command. */ - return CommandCost(); + if (!send_net) { + /* Prepare for command execution. */ + _cleared_object_areas.clear(); + BasePersistentStorageArray::SwitchMode(PSM_ENTER_COMMAND); } - Debug(desync, 1, "cmd: {:08x}; {:02x}; {:02x}; {:08x}; {:08x}; {:06x}; {} ({})", _date, _date_fract, (int)_current_company, cmd, err_message, tile, CommandParametersToHexString(tile, p1, p2, text), GetCommandName(cmd)); - /* Actually try and execute the command. If no cost-type is given - * use the construction one */ - _cleared_object_areas.clear(); - BasePersistentStorageArray::SwitchMode(PSM_ENTER_COMMAND); - CommandCost res2 = proc(flags | DC_EXEC, tile, p1, p2, text); + return { false, _debug_desync_level >= 1, send_net }; +} + +/** + * Process the result of a command test run and execution run. + * @param cmd Command that was executed. + * @param cmd_flags Command flags. + * @param res_test Command result of test run. + * @param tes_exec Command result of real run. + * @param tile Tile of command execution. + * @param[in,out] cur_company Backup of current company at start of command execution. + * @return Final command result. + */ +CommandCost CommandHelperBase::InternalExecuteProcessResult(Commands cmd, CommandFlags cmd_flags, const CommandCost &res_test, const CommandCost &res_exec, TileIndex tile, Backup &cur_company) +{ BasePersistentStorageArray::SwitchMode(PSM_LEAVE_COMMAND); if (cmd == CMD_COMPANY_CTRL) { @@ -395,7 +374,7 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba _current_company = _local_company; } else { /* Make sure nothing bad happened, like changing the current company. */ - assert(exec_as_spectator ? _current_company == COMPANY_SPECTATOR : cur_company.Verify()); + assert((cmd_flags & (CMD_SPECTATOR | CMD_SERVER)) != 0 ? _current_company == COMPANY_SPECTATOR : cur_company.Verify()); cur_company.Restore(); } @@ -403,15 +382,16 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba * return of the command. Otherwise we can check whether the * test and execution have yielded the same result, * i.e. cost and error state are the same. */ + bool test_and_exec_can_differ = (cmd_flags & CMD_NO_TEST) != 0; if (!test_and_exec_can_differ) { - assert(res.GetCost() == res2.GetCost() && res.Failed() == res2.Failed()); // sanity check - } else if (res2.Failed()) { - return res2; + assert(res_test.GetCost() == res_exec.GetCost() && res_test.Failed() == res_exec.Failed()); // sanity check + } else if (res_exec.Failed()) { + return res_exec; } /* If we're needing more money and we haven't done * anything yet, ask for the money! */ - if (_additional_cash_required != 0 && res2.GetCost() == 0) { + if (_additional_cash_required != 0 && res_exec.GetCost() == 0) { /* It could happen we removed rail, thus gained money, and deleted something else. * So make sure the signal buffer is empty even in this case */ UpdateSignalsInBuffer(); @@ -425,12 +405,12 @@ CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallba if (c != nullptr) c->last_build_coordinate = tile; } - SubtractMoneyFromCompany(res2); + SubtractMoneyFromCompany(res_exec); /* update signals if needed */ UpdateSignalsInBuffer(); - return res2; + return res_exec; } diff --git a/src/command_func.h b/src/command_func.h index 9d603abcf6..b69e97b393 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -12,6 +12,8 @@ #include "command_type.h" #include "company_type.h" +#include "company_func.h" +#include "core/backup_type.hpp" #include "misc/endian_buffer.hpp" #include "tile_map.h" @@ -34,9 +36,6 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); */ #define return_cmd_error(errcode) return CommandCost(errcode); -CommandCost DoCommandPInternal(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); - -void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex location, const CommandDataBuffer &cmd_data); extern Money _additional_cash_required; @@ -87,6 +86,10 @@ protected: static void InternalDoAfter(CommandCost &res, DoCommandFlag flags, bool top_level, bool test); static std::tuple InternalPostBefore(Commands cmd, CommandFlags flags, TileIndex tile, StringID err_message, bool network_command); static void InternalPostResult(const CommandCost &res, TileIndex tile, bool estimate_only, bool only_sending, StringID err_message, bool my_cmd); + static bool InternalExecutePrepTest(CommandFlags cmd_flags, TileIndex tile, Backup &cur_company); + static std::tuple InternalExecuteValidateTestAndPrepExec(CommandCost &res, CommandFlags cmd_flags, bool estimate_only, bool network_command, Backup &cur_company); + static CommandCost InternalExecuteProcessResult(Commands cmd, CommandFlags cmd_flags, const CommandCost &res_test, const CommandCost &res_exec, TileIndex tile, Backup &cur_company); + static void LogCommandExecution(Commands cmd, StringID err_message, TileIndex tile, const CommandDataBuffer &args, bool failed); }; /** @@ -186,6 +189,41 @@ public: return InternalPost(err_message, callback, my_cmd, true, location, std::move(args)); } + /** + * Prepare a command to be send over the network + * @param cmd The command to execute (a CMD_* value) + * @param err_message Message prefix to show on error + * @param callback A callback function to call after the command is finished + * @param company The company that wants to send the command + * @param args Parameters for the command + */ + static void SendNet(StringID err_message, CommandCallback *callback, CompanyID company, Targs... args) + { + auto args_tuple = std::forward_as_tuple(args...); + + TileIndex tile{}; + if constexpr (std::is_same_v>) { + tile = std::get<0>(args_tuple); + } + + ::NetworkSendCommand(Tcmd, err_message, callback, _current_company, tile, EndianBufferWriter::FromValue(args_tuple)); + } + + /** + * Top-level network safe command execution without safety checks. + * @param err_message Message prefix to show on error + * @param callback A callback function to call after the command is finished + * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) + * @param estimate_only whether to give only the estimate or also execute the command + * @param location Tile location for user feedback. + * @param args Parameters for the command + * @return the command cost of this function. + */ + static CommandCost Unsafe(StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, TileIndex location, std::tuple args) + { + return Execute(err_message, callback, my_cmd, estimate_only, false, location, std::move(args)); + } + protected: static bool InternalPost(StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, std::tuple args) { @@ -206,7 +244,7 @@ protected: /* Only set p2 when the command does not come from the network. */ if (!network_command && GetCommandFlags() & CMD_CLIENT_ID && std::get<2>(args) == 0) std::get<2>(args) = CLIENT_ID_SERVER; - CommandCost res = std::apply(DoCommandPInternal, std::tuple_cat(std::make_tuple(Tcmd, err_message, callback, my_cmd, estimate_only, network_command), args)); + CommandCost res = Execute(err_message, callback, my_cmd, estimate_only, network_command, tile, args); InternalPostResult(res, tile, estimate_only, only_sending, err_message, my_cmd); if (!estimate_only && !only_sending && callback != nullptr) { @@ -215,6 +253,56 @@ protected: return res.Succeeded(); } + + static CommandCost Execute(StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, std::tuple args) + { + /* Prevent recursion; it gives a mess over the network */ + RecursiveCommandCounter counter{}; + assert(counter.IsTopLevel()); + + /* Command flags are used internally */ + CommandFlags cmd_flags = GetCommandFlags(); + + /* Make sure p2 is properly set to a ClientID also when processing external commands. */ + assert(!(cmd_flags & CMD_CLIENT_ID) || std::get<2>(args) != 0); + + Backup cur_company(_current_company, FILE_LINE); + if (!InternalExecutePrepTest(cmd_flags, tile, cur_company)) { + cur_company.Trash(); + return CMD_ERROR; + } + + /* Test the command. */ + DoCommandFlag flags = CommandFlagsToDCFlags(cmd_flags); + CommandCost res = std::apply(CommandTraits::proc, std::tuple_cat(std::make_tuple(flags), args)); + + auto [exit_test, desync_log, send_net] = InternalExecuteValidateTestAndPrepExec(res, cmd_flags, estimate_only, network_command, cur_company); + if (exit_test) { + if (desync_log) LogCommandExecution(Tcmd, err_message, tile, EndianBufferWriter::FromValue(args), true); + cur_company.Restore(); + return res; + } + + /* If we are in network, and the command is not from the network + * send it to the command-queue and abort execution. */ + if (send_net) { + ::NetworkSendCommand(Tcmd, err_message, callback, _current_company, tile, EndianBufferWriter::FromValue(args)); + cur_company.Restore(); + + /* Don't return anything special here; no error, no costs. + * This way it's not handled by DoCommand and only the + * actual execution of the command causes messages. Also + * reset the storages as we've not executed the command. */ + return CommandCost(); + } + + if (desync_log) LogCommandExecution(Tcmd, err_message, tile, EndianBufferWriter::FromValue(args), false); + + /* Actually try and execute the command. */ + CommandCost res2 = std::apply(CommandTraits::proc, std::tuple_cat(std::make_tuple(flags | DC_EXEC), args)); + + return InternalExecuteProcessResult(Tcmd, cmd_flags, res, res2, tile, cur_company); + } }; template diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index dd42f5f6ff..cc7cd8336e 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -18,6 +18,7 @@ #include "../company_func.h" #include "../company_base.h" #include "../company_gui.h" +#include "../company_cmd.h" #include "../core/random_func.hpp" #include "../date_func.h" #include "../gfx_func.h" @@ -839,7 +840,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet * the server will give us a client-id and let us in */ _network_join_status = NETWORK_JOIN_STATUS_REGISTERING; ShowJoinStatusWindow(); - NetworkSendCommand(CMD_COMPANY_CTRL, STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); + Command::SendNet(STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); } } else { /* take control over an existing company */ diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 983f4b5659..f99c71b97c 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -176,22 +176,6 @@ static CommandQueue _local_wait_queue; /** Local queue of packets waiting for execution. */ static CommandQueue _local_execution_queue; -/** - * Prepare a DoCommand to be send over the network - * @param cmd The command to execute (a CMD_* value) - * @param err_message Message prefix to show on error - * @param callback A callback function to call after the command is finished - * @param company The company that wants to send the command - * @param tile The tile to perform a command on (see #CommandProc) - * @param p1 Additional data for the command (see #CommandProc) - * @param p2 Additional data for the command (see #CommandProc) - * @param text The text to pass - */ -void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) -{ - auto data = EndianBufferWriter::FromValue(std::make_tuple(tile, p1, p2, text)); - NetworkSendCommand(cmd, err_message, callback, company, tile, data); -} /** * Prepare a DoCommand to be send over the network diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index a2b34593eb..ac12402ea5 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1538,7 +1538,7 @@ private: if (_network_server) { Command::Post(0, CCA_NEW, _network_own_client_id, {}); } else { - NetworkSendCommand(CMD_COMPANY_CTRL, STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); + Command::SendNet(STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); } } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 65f3188de8..ad891aef8c 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -2081,7 +2081,7 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci) /* ci is nullptr when replaying, or for AIs. In neither case there is a client. */ ci->client_playas = c->index; NetworkUpdateClientInfo(ci->client_id); - NetworkSendCommand(CMD_RENAME_PRESIDENT, STR_NULL, nullptr, c->index, 0, 0, 0, ci->client_name); + Command::SendNet(STR_NULL, nullptr, c->index, 0, 0, 0, ci->client_name); } /* Announce new company on network. */ diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 987b3154f2..6bececc0cc 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -200,7 +200,7 @@ CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, uint32 p1, /* We need to circumvent the "prevention" from this command being executed * while the game is paused, so use the internal method. Nor do we want * this command to get its cost estimated when shift is pressed. */ - DoCommandPInternal(CMD_CLEAR_ORDER_BACKUP, STR_NULL, nullptr, true, false, false, ob->tile, 0, user, {}); + Command::Unsafe(STR_NULL, nullptr, true, false, ob->tile, CommandTraits::Args{ ob->tile, 0, user, {} }); } else { /* The command came from the game logic, i.e. the clearing of a tile. * In that case we have no need to actually sync this, just do it. */ diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index cfb6d393a4..26da500c4c 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -371,7 +371,7 @@ bool ScriptObject::ScriptDoCommandHelper::FromValue(args), Tcmd); /* Try to perform the command. */ - CommandCost res = std::apply(&DoCommandPInternal, std::tuple_cat(std::make_tuple(Tcmd, (StringID)0, networking ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, false), args)); + CommandCost res = ::Command::Unsafe((StringID)0, networking ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, tile, args); return ScriptObject::DoCommandProcessResult(res, callback, estimate_only); } diff --git a/src/settings.cpp b/src/settings.cpp index 63c7478a04..3c0f92f39b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1604,7 +1604,7 @@ void SyncCompanySettings() const SettingDesc *sd = GetSettingDesc(desc); uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object); uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object); - if (old_value != new_value) NetworkSendCommand(CMD_CHANGE_COMPANY_SETTING, STR_NULL, nullptr, _local_company, 0, 0, new_value, sd->GetName()); + if (old_value != new_value) Command::SendNet(STR_NULL, nullptr, _local_company, 0, 0, new_value, sd->GetName()); } } From 4f3ea3907e23428461c626b6c861d834b358bc9f Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Tue, 2 Nov 2021 21:34:39 +0100 Subject: [PATCH 20/60] Codechange: Un-bitstuff commands taking a ClientID (i.e. CMD_CLIENT_ID). --- src/ai/ai_gui.cpp | 4 +- src/aircraft_cmd.cpp | 3 +- src/aircraft_cmd.h | 2 +- src/autoreplace_cmd.cpp | 16 ++++---- src/build_vehicle_gui.cpp | 4 +- src/command.cpp | 8 ++-- src/command_func.h | 47 +++++++++++++++++++++--- src/company_cmd.cpp | 19 +++------- src/company_cmd.h | 4 +- src/company_type.h | 6 ++- src/console_cmds.cpp | 10 ++--- src/depot_gui.cpp | 4 +- src/economy.cpp | 2 +- src/network/network_client.cpp | 2 +- src/network/network_command.cpp | 42 ++++++++++++++++----- src/network/network_gui.cpp | 6 +-- src/network/network_server.cpp | 10 ++--- src/order_backup.cpp | 12 +++--- src/order_cmd.h | 2 +- src/roadveh_cmd.cpp | 3 +- src/roadveh_cmd.h | 2 +- src/script/api/script_object.hpp | 20 +++++++++- src/script/api/script_vehicle.cpp | 8 ++-- src/ship_cmd.cpp | 3 +- src/ship_cmd.h | 2 +- src/train_cmd.cpp | 22 +++++------ src/train_cmd.h | 4 +- src/vehicle_cmd.cpp | 61 ++++++++++++++----------------- src/vehicle_cmd.h | 4 +- 29 files changed, 196 insertions(+), 136 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 5996039c9d..5e0c720f00 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -1292,8 +1292,8 @@ struct AIDebugWindow : public Window { case WID_AID_RELOAD_TOGGLE: if (ai_debug_company == OWNER_DEITY) break; /* First kill the company of the AI, then start a new one. This should start the current AI again */ - Command::Post(0, CCA_DELETE | ai_debug_company << 16 | CRR_MANUAL << 24, 0, {}); - Command::Post(0, CCA_NEW_AI | ai_debug_company << 16, 0, {}); + Command::Post(CCA_DELETE, ai_debug_company, CRR_MANUAL, INVALID_CLIENT_ID); + Command::Post(CCA_NEW_AI, ai_debug_company, CRR_NONE, INVALID_CLIENT_ID); break; case WID_AID_SETTINGS: diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 998f75e6bd..f1263f00cd 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -263,11 +263,10 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoff * @param flags type of operation. * @param tile tile of the depot where aircraft is built. * @param e the engine to build. - * @param data unused. * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ -CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **ret) +CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **ret) { const AircraftVehicleInfo *avi = &e->u.air; const Station *st = Station::GetByTile(tile); diff --git a/src/aircraft_cmd.h b/src/aircraft_cmd.h index 719974af7b..df58739a54 100644 --- a/src/aircraft_cmd.h +++ b/src/aircraft_cmd.h @@ -14,6 +14,6 @@ #include "engine_type.h" #include "vehicle_type.h" -CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **v); +CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **v); #endif /* AIRCRAFT_CMD_H */ diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 4ba41942c9..6a8937cb65 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -345,7 +345,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic } /* Build the new vehicle */ - cost = Command::Do(DC_EXEC | DC_AUTOREPLACE, old_veh->tile, e | (CT_INVALID << 24), 0, {}); + cost = Command::Do(DC_EXEC | DC_AUTOREPLACE, old_veh->tile, e, true, CT_INVALID, INVALID_CLIENT_ID); if (cost.Failed()) return cost; Vehicle *new_veh = Vehicle::Get(_new_vehicle_id); @@ -471,11 +471,11 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b } /* Sell the old vehicle */ - cost.AddCost(Command::Do(flags, 0, old_v->index, 0, {})); + cost.AddCost(Command::Do(flags, 0, old_v->index, false, false, INVALID_CLIENT_ID)); /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - Command::Do(DC_EXEC, 0, new_v->index, 0, {}); + Command::Do(DC_EXEC, 0, new_v->index, false, false, INVALID_CLIENT_ID); } } @@ -602,7 +602,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON); /* Sell wagon */ - [[maybe_unused]] CommandCost ret = Command::Do(DC_EXEC, 0, wagon->index, 0, {}); + [[maybe_unused]] CommandCost ret = Command::Do(DC_EXEC, 0, wagon->index, false, false, INVALID_CLIENT_ID); assert(ret.Succeeded()); new_vehs[i] = nullptr; @@ -634,7 +634,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Sell the vehicle. * Note: This might temporarily construct new trains, so use DC_AUTOREPLACE to prevent * it from failing due to engine limits. */ - cost.AddCost(Command::Do(flags | DC_AUTOREPLACE, 0, w->index, 0, {})); + cost.AddCost(Command::Do(flags | DC_AUTOREPLACE, 0, w->index, false, false, INVALID_CLIENT_ID)); if ((flags & DC_EXEC) != 0) { old_vehs[i] = nullptr; if (i == 0) old_head = nullptr; @@ -665,7 +665,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon if ((flags & DC_EXEC) == 0) { for (int i = num_units - 1; i >= 0; i--) { if (new_vehs[i] != nullptr) { - Command::Do(DC_EXEC, 0, new_vehs[i]->index, 0, {}); + Command::Do(DC_EXEC, 0, new_vehs[i]->index, false, false, INVALID_CLIENT_ID); new_vehs[i] = nullptr; } } @@ -696,12 +696,12 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon } /* Sell the old vehicle */ - cost.AddCost(Command::Do(flags, 0, old_head->index, 0, {})); + cost.AddCost(Command::Do(flags, 0, old_head->index, false, false, INVALID_CLIENT_ID)); } /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - Command::Do(DC_EXEC, 0, new_head->index, 0, {}); + Command::Do(DC_EXEC, 0, new_head->index, false, false, INVALID_CLIENT_ID); } } } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 639bab7a9f..ef87699ef8 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1229,7 +1229,7 @@ struct BuildVehicleWindow : Window { if (!this->listview_mode) { /* Query for cost and refitted capacity */ - CommandCost ret = Command::Do(DC_QUERY_COST, this->window_number, this->sel_engine | (cargo << 24), 0, {}); + CommandCost ret = Command::Do(DC_QUERY_COST, this->window_number, this->sel_engine, true, cargo, INVALID_CLIENT_ID); if (ret.Succeeded()) { this->te.cost = ret.GetCost() - e->GetCost(); this->te.capacity = _returned_refit_capacity; @@ -1472,7 +1472,7 @@ struct BuildVehicleWindow : Window { CommandCallback *callback = (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildPrimaryVehicle; CargoID cargo = this->cargo_filter[this->cargo_filter_criteria]; if (cargo == CF_ANY || cargo == CF_ENGINES) cargo = CF_NONE; - Command::Post(GetCmdBuildVehMsg(this->vehicle_type), callback, this->window_number, sel_eng | (cargo << 24), 0, {}); + Command::Post(GetCmdBuildVehMsg(this->vehicle_type), callback, this->window_number, sel_eng, true, cargo, INVALID_CLIENT_ID); } break; } diff --git a/src/command.cpp b/src/command.cpp index 9997a66fec..08fe7b2659 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -75,15 +75,13 @@ int RecursiveCommandCounter::_counter = 0; * the #CMD_AUTO, #CMD_OFFLINE and #CMD_SERVER values. */ struct CommandInfo { - CommandProc *proc; ///< The procedure to actually executing const char *name; ///< A human readable name for the procedure CommandFlags flags; ///< The (command) flags to that apply to this command CommandType type; ///< The type of command. }; /* Helpers to generate the master command table from the command traits. */ - template -inline constexpr CommandInfo CommandFromTrait() noexcept { return { T::proc, T::name, T::flags, T::type }; }; +inline constexpr CommandInfo CommandFromTrait() noexcept { return { T::name, T::flags, T::type }; }; template inline constexpr auto MakeCommandsFromTraits(std::integer_sequence) noexcept { @@ -101,14 +99,14 @@ static constexpr auto _command_proc_table = MakeCommandsFromTraits(std::make_int /*! - * This function range-checks a cmd, and checks if the cmd is not nullptr + * This function range-checks a cmd. * * @param cmd The integer value of a command * @return true if the command is valid (and got a CommandProc function) */ bool IsValidCommand(Commands cmd) { - return cmd < _command_proc_table.size() && _command_proc_table[cmd].proc != nullptr; + return cmd < _command_proc_table.size(); } /*! diff --git a/src/command_func.h b/src/command_func.h index b69e97b393..e1f958f5bd 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -11,6 +11,7 @@ #define COMMAND_FUNC_H #include "command_type.h" +#include "network/network_type.h" #include "company_type.h" #include "company_func.h" #include "core/backup_type.hpp" @@ -225,6 +226,22 @@ public: } protected: + /** Helper to process a single ClientID argument. */ + template + static inline void SetClientIdHelper(T &data) + { + if constexpr (std::is_same_v) { + if (data == INVALID_CLIENT_ID) data = CLIENT_ID_SERVER; + } + } + + /** Set all invalid ClientID's to the proper value. */ + template + static inline void SetClientIds(Ttuple &values, std::index_sequence) + { + ((SetClientIdHelper(std::get(values))), ...); + } + static bool InternalPost(StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, std::tuple args) { /* Where to show the message? */ @@ -241,8 +258,8 @@ protected: auto [err, estimate_only, only_sending] = InternalPostBefore(Tcmd, GetCommandFlags(), tile, err_message, network_command); if (err) return false; - /* Only set p2 when the command does not come from the network. */ - if (!network_command && GetCommandFlags() & CMD_CLIENT_ID && std::get<2>(args) == 0) std::get<2>(args) = CLIENT_ID_SERVER; + /* Only set client IDs when the command does not come from the network. */ + if (!network_command && GetCommandFlags() & CMD_CLIENT_ID) SetClientIds(args, std::index_sequence_for{}); CommandCost res = Execute(err_message, callback, my_cmd, estimate_only, network_command, tile, args); InternalPostResult(res, tile, estimate_only, only_sending, err_message, my_cmd); @@ -254,6 +271,24 @@ protected: return res.Succeeded(); } + /** Helper to process a single ClientID argument. */ + template + static inline bool ClientIdIsSet(T &data) + { + if constexpr (std::is_same_v) { + return data != INVALID_CLIENT_ID; + } else { + return true; + } + } + + /** Check if all ClientID arguments are set to valid values. */ + template + static inline bool AllClientIdsSet(Ttuple &values, std::index_sequence) + { + return (ClientIdIsSet(std::get(values)) && ...); + } + static CommandCost Execute(StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, bool network_command, TileIndex tile, std::tuple args) { /* Prevent recursion; it gives a mess over the network */ @@ -261,10 +296,12 @@ protected: assert(counter.IsTopLevel()); /* Command flags are used internally */ - CommandFlags cmd_flags = GetCommandFlags(); + constexpr CommandFlags cmd_flags = GetCommandFlags(); - /* Make sure p2 is properly set to a ClientID also when processing external commands. */ - assert(!(cmd_flags & CMD_CLIENT_ID) || std::get<2>(args) != 0); + if constexpr ((cmd_flags & CMD_CLIENT_ID) != 0) { + /* Make sure arguments are properly set to a ClientID also when processing external commands. */ + assert(AllClientIdsSet(args, std::index_sequence_for{})); + } Backup cur_company(_current_company, FILE_LINE); if (!InternalExecutePrepTest(cmd_flags, tile, cur_company)) { diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index cf44af25c7..87231f3eb6 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -604,7 +604,7 @@ static bool MaybeStartNewCompany() if (n < (uint)_settings_game.difficulty.max_no_competitors) { /* Send a command to all clients to start up a new AI. * Works fine for Multiplayer and Singleplayer */ - return Command::Post(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, {}); + return Command::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID ); } return false; @@ -796,21 +796,16 @@ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason) /** * Control the companies: add, delete, etc. * @param flags operation to perform - * @param tile unused - * @param p1 various functionality - * - bits 0..15: CompanyCtrlAction - * - bits 16..23: CompanyID - * - bits 24..31: CompanyRemoveReason (with CCA_DELETE) - * @param p2 ClientID - * @param text unused + * @param cca action to perform + * @param company_id company to perform the action on + * @param client_id ClientID * @return the cost of this operation or an error */ -CommandCost CmdCompanyCtrl(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id) { InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0); - CompanyID company_id = (CompanyID)GB(p1, 16, 8); - switch ((CompanyCtrlAction)GB(p1, 0, 16)) { + switch (cca) { case CCA_NEW: { // Create a new company /* This command is only executed in a multiplayer game */ if (!_networking) return CMD_ERROR; @@ -818,7 +813,6 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 /* Has the network client a correct ClientIndex? */ if (!(flags & DC_EXEC)) return CommandCost(); - ClientID client_id = (ClientID)p2; NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); /* Delete multiplayer progress bar */ @@ -873,7 +867,6 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 } case CCA_DELETE: { // Delete a company - CompanyRemoveReason reason = (CompanyRemoveReason)GB(p1, 24, 8); if (reason >= CRR_END) return CMD_ERROR; /* We can't delete the last existing company in singleplayer mode. */ diff --git a/src/company_cmd.h b/src/company_cmd.h index 0d3e2d2fd6..107a77f29c 100644 --- a/src/company_cmd.h +++ b/src/company_cmd.h @@ -12,7 +12,9 @@ #include "command_type.h" -CommandProc CmdCompanyCtrl; +enum ClientID : uint32; + +CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id); CommandProc CmdGiveMoney; CommandProc CmdRenameCompany; CommandProc CmdRenamePresident; diff --git a/src/company_type.h b/src/company_type.h index de2556b914..8da3133082 100644 --- a/src/company_type.h +++ b/src/company_type.h @@ -52,16 +52,18 @@ struct Company; typedef uint32 CompanyManagerFace; ///< Company manager face bits, info see in company_manager_face.h /** The reason why the company was removed. */ -enum CompanyRemoveReason { +enum CompanyRemoveReason : uint8 { CRR_MANUAL, ///< The company is manually removed. CRR_AUTOCLEAN, ///< The company is removed due to autoclean. CRR_BANKRUPT, ///< The company went belly-up. CRR_END, ///< Sentinel for end. + + CRR_NONE = CRR_MANUAL, ///< Dummy reason for actions that don't need one. }; /** The action to do with CMD_COMPANY_CTRL. */ -enum CompanyCtrlAction { +enum CompanyCtrlAction : uint8 { CCA_NEW, ///< Create a new company. CCA_NEW_AI, ///< Create a new AI company. CCA_DELETE, ///< Delete a company. diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 42a94aa89f..9e244dd439 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -865,7 +865,7 @@ DEF_CONSOLE_CMD(ConResetCompany) } /* It is safe to remove this company */ - Command::Post(0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0, {}); + Command::Post(CCA_DELETE, index, CRR_MANUAL, INVALID_CLIENT_ID); IConsolePrint(CC_DEFAULT, "Company deleted."); return true; @@ -1222,7 +1222,7 @@ DEF_CONSOLE_CMD(ConStartAI) } /* Start a new AI company */ - Command::Post(0, CCA_NEW_AI | INVALID_COMPANY << 16, 0, {}); + Command::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID); return true; } @@ -1258,8 +1258,8 @@ DEF_CONSOLE_CMD(ConReloadAI) } /* First kill the company of the AI, then start a new one. This should start the current AI again */ - Command::Post(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, {}); - Command::Post(0, CCA_NEW_AI | company_id << 16, 0, {}); + Command::Post(CCA_DELETE, company_id, CRR_MANUAL, INVALID_CLIENT_ID); + Command::Post(CCA_NEW_AI, company_id, CRR_NONE, INVALID_CLIENT_ID); IConsolePrint(CC_DEFAULT, "AI reloaded."); return true; @@ -1296,7 +1296,7 @@ DEF_CONSOLE_CMD(ConStopAI) } /* Now kill the company of the AI. */ - Command::Post(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, {}); + Command::Post(CCA_DELETE, company_id, CRR_MANUAL, INVALID_CLIENT_ID); IConsolePrint(CC_DEFAULT, "AI stopped, company deleted."); return true; diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index d316d97ca0..830bdbaeed 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -1026,8 +1026,8 @@ struct DepotWindow : Window { this->sel = INVALID_VEHICLE; this->SetDirty(); - int sell_cmd = (v->type == VEH_TRAIN && (widget == WID_D_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0; - Command::Post(GetCmdSellVehMsg(v->type), v->tile, v->index | sell_cmd << 20 | MAKE_ORDER_BACKUP_FLAG, 0, {}); + bool sell_cmd = (v->type == VEH_TRAIN && (widget == WID_D_SELL_CHAIN || _ctrl_pressed)); + Command::Post(GetCmdSellVehMsg(v->type), v->tile, v->index, sell_cmd, true, INVALID_CLIENT_ID); break; } diff --git a/src/economy.cpp b/src/economy.cpp index c65d997b80..8bf608a864 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -630,7 +630,7 @@ static void CompanyCheckBankrupt(Company *c) * player we are sure (the above check) that we are not the local * company and thus we won't be moved. */ if (!_networking || _network_server) { - Command::Post(0, CCA_DELETE | (c->index << 16) | (CRR_BANKRUPT << 24), 0, {}); + Command::Post(CCA_DELETE, c->index, CRR_BANKRUPT, INVALID_CLIENT_ID); return; } break; diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index cc7cd8336e..1868f5e603 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -840,7 +840,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet * the server will give us a client-id and let us in */ _network_join_status = NETWORK_JOIN_STATUS_REGISTERING; ShowJoinStatusWindow(); - Command::SendNet(STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); + Command::SendNet(STR_NULL, nullptr, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID); } } else { /* take control over an existing company */ diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index f99c71b97c..58de73b198 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -89,15 +89,17 @@ static CommandCallback * const _callback_table[] = { template static CommandDataBuffer SanitizeCmdStrings(const CommandDataBuffer &data); template static void UnpackNetworkCommand(const CommandPacket *cp); +template static void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id); struct CommandDispatch { CommandDataBuffer(*Sanitize)(const CommandDataBuffer &); + void (*ReplaceClientId)(CommandPacket &, ClientID); void (*Unpack)(const CommandPacket *); }; template inline constexpr auto MakeDispatchTable(std::integer_sequence) noexcept { - return std::array{{ { &SanitizeCmdStrings(i)>, &UnpackNetworkCommand(i)> }... }}; + return std::array{{ { &SanitizeCmdStrings(i)>, &NetworkReplaceCommandClientId(i)>, &UnpackNetworkCommand(i)> }... }}; } static constexpr auto _cmd_dispatch = MakeDispatchTable(std::make_integer_sequence, CMD_END>{}); @@ -383,23 +385,45 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp) p->Send_uint8 (callback); } -/** - * Insert a client ID into the command data in a command packet. - * @param cp Command packet to modify. - * @param client_id Client id to insert. - */ -void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id) +/** Helper to process a single ClientID argument. */ +template +static inline void SetClientIdHelper(T &data, [[maybe_unused]] ClientID client_id) +{ + if constexpr (std::is_same_v) { + data = client_id; + } +} + +/** Set all invalid ClientID's to the proper value. */ +template +static inline void SetClientIds(Ttuple &values, ClientID client_id, std::index_sequence) +{ + ((SetClientIdHelper(std::get(values), client_id)), ...); +} + +template +static void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id) { /* Unpack command parameters. */ - auto params = EndianBufferReader::ToValue>(cp.data); + auto params = EndianBufferReader::ToValue::Args>(cp.data); /* Insert client id. */ - std::get<2>(params) = client_id; + SetClientIds(params, client_id, std::make_index_sequence>{}); /* Repack command parameters. */ cp.data = EndianBufferWriter::FromValue(params); } +/** + * Insert a client ID into the command data in a command packet. + * @param cp Command packet to modify. + * @param client_id Client id to insert. + */ +void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id) +{ + _cmd_dispatch[cp.cmd].ReplaceClientId(cp, client_id); +} + /** Validate a single string argument coming from network. */ template diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index ac12402ea5..0c7e361dd4 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1396,7 +1396,7 @@ static void AdminCompanyResetCallback(Window *w, bool confirmed) { if (confirmed) { if (NetworkCompanyHasClients(_admin_company_id)) return; - Command::Post(0, CCA_DELETE | _admin_company_id << 16 | CRR_MANUAL << 24, 0, {}); + Command::Post(CCA_DELETE, _admin_company_id, CRR_MANUAL, INVALID_CLIENT_ID); } } @@ -1536,9 +1536,9 @@ private: static void OnClickCompanyNew(NetworkClientListWindow *w, Point pt, CompanyID company_id) { if (_network_server) { - Command::Post(0, CCA_NEW, _network_own_client_id, {}); + Command::Post(CCA_NEW, INVALID_COMPANY, CRR_NONE, _network_own_client_id); } else { - Command::SendNet(STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {}); + Command::SendNet(STR_NULL, nullptr, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID); } } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index ad891aef8c..197d398bf6 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1050,15 +1050,15 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet * to match the company in the packet. If it doesn't, the client has done * something pretty naughty (or a bug), and will be kicked */ - uint32 company_p1 = cp.cmd == CMD_COMPANY_CTRL ? std::get<1>(EndianBufferReader::ToValue::Args>(cp.data)) : 0; - if (!(cp.cmd == CMD_COMPANY_CTRL && company_p1 == 0 && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) { + CompanyCtrlAction cca = cp.cmd == CMD_COMPANY_CTRL ? std::get<0>(EndianBufferReader::ToValue::Args>(cp.data)) : CCA_NEW; + if (!(cp.cmd == CMD_COMPANY_CTRL && cca == CCA_NEW && ci->client_playas == COMPANY_NEW_COMPANY) && ci->client_playas != cp.company) { IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a command as another company {}.", ci->client_playas + 1, this->GetClientIP(), cp.company + 1); return this->SendError(NETWORK_ERROR_COMPANY_MISMATCH); } if (cp.cmd == CMD_COMPANY_CTRL) { - if (company_p1 != 0 || cp.company != COMPANY_SPECTATOR) { + if (cca != CCA_NEW || cp.company != COMPANY_SPECTATOR) { return this->SendError(NETWORK_ERROR_CHEATER); } @@ -1556,7 +1556,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_unprotected-months, and is there no protection? */ if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) { /* Shut the company down */ - Command::Post(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, {}); + Command::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID); IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no password.", c->index + 1); } /* Is the company empty for autoclean_protected-months, and there is a protection? */ @@ -1570,7 +1570,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_novehicles-months, and has no vehicles? */ if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) { /* Shut the company down */ - Command::Post(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, {}); + Command::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID); IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no vehicles.", c->index + 1); } } else { diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 6bececc0cc..69ae6507db 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -144,15 +144,13 @@ void OrderBackup::DoRestore(Vehicle *v) * Clear an OrderBackup * @param flags For command. * @param tile Tile related to the to-be-cleared OrderBackup. - * @param p1 Unused. - * @param p2 User that had the OrderBackup. - * @param text Unused. + * @param user_id User that had the OrderBackup. * @return The cost of this operation or an error. */ -CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id) { /* No need to check anything. If the tile or user don't exist we just ignore it. */ - if (flags & DC_EXEC) OrderBackup::ResetOfUser(tile == 0 ? INVALID_TILE : tile, p2); + if (flags & DC_EXEC) OrderBackup::ResetOfUser(tile == 0 ? INVALID_TILE : tile, user_id); return CommandCost(); } @@ -171,7 +169,7 @@ CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, uint32 p1, /* If it's not a backup of us, ignore it. */ if (ob->user != user) continue; - Command::Post(0, 0, user, {}); + Command::Post(0, static_cast(user)); return; } } @@ -200,7 +198,7 @@ CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, uint32 p1, /* We need to circumvent the "prevention" from this command being executed * while the game is paused, so use the internal method. Nor do we want * this command to get its cost estimated when shift is pressed. */ - Command::Unsafe(STR_NULL, nullptr, true, false, ob->tile, CommandTraits::Args{ ob->tile, 0, user, {} }); + Command::Unsafe(STR_NULL, nullptr, true, false, ob->tile, CommandTraits::Args{ ob->tile, static_cast(user) }); } else { /* The command came from the game logic, i.e. the clearing of a tile. * In that case we have no need to actually sync this, just do it. */ diff --git a/src/order_cmd.h b/src/order_cmd.h index 606cbef605..fa3424ce42 100644 --- a/src/order_cmd.h +++ b/src/order_cmd.h @@ -19,7 +19,7 @@ CommandProc CmdInsertOrder; CommandProc CmdOrderRefit; CommandProc CmdCloneOrder; CommandProc CmdMoveOrder; -CommandProc CmdClearOrderBackup; +CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id); DEF_CMD_TRAIT(CMD_MODIFY_ORDER, CmdModifyOrder, 0, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_SKIP_TO_ORDER, CmdSkipToOrder, 0, CMDT_ROUTE_MANAGEMENT) diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index efe45c507d..a6442430e0 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -254,11 +254,10 @@ void RoadVehUpdateCache(RoadVehicle *v, bool same_length) * @param flags type of operation. * @param tile tile of the depot where road vehicle is built. * @param e the engine to build. - * @param data unused. * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ -CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **ret) +CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **ret) { /* Check that the vehicle can drive on the road in question */ RoadType rt = e->u.road.roadtype; diff --git a/src/roadveh_cmd.h b/src/roadveh_cmd.h index ca99dee3ab..94aaee743f 100644 --- a/src/roadveh_cmd.h +++ b/src/roadveh_cmd.h @@ -14,7 +14,7 @@ #include "engine_type.h" #include "vehicle_type.h" -CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **v); +CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **v); CommandProc CmdTurnRoadVeh; diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index 26da500c4c..8d9be14c46 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -347,6 +347,22 @@ namespace ScriptObjectInternal { { ((SanitizeSingleStringHelper(std::get(values))), ...); } + + /** Helper to process a single ClientID argument. */ + template + static inline void SetClientIdHelper(T &data) + { + if constexpr (std::is_same_v) { + if (data == INVALID_CLIENT_ID) data = (ClientID)UINT32_MAX; + } + } + + /** Set all invalid ClientID's to the proper value. */ + template + static inline void SetClientIds(Ttuple &values, std::index_sequence) + { + ((SetClientIdHelper(std::get(values))), ...); + } } template @@ -364,8 +380,8 @@ bool ScriptObject::ScriptDoCommandHelper(args); } - /* Only set p2 when the command does not come from the network. */ - if ((::GetCommandFlags() & CMD_CLIENT_ID) != 0 && std::get<2>(args) == 0) std::get<2>(args) = UINT32_MAX; + /* Only set ClientID parameters when the command does not come from the network. */ + if constexpr ((::GetCommandFlags() & CMD_CLIENT_ID) != 0) ScriptObjectInternal::SetClientIds(args, std::index_sequence_for{}); /* Store the command for command callback validation. */ if (!estimate_only && networking) ScriptObject::SetLastCommand(tile, EndianBufferWriter::FromValue(args), Tcmd); diff --git a/src/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp index d245f41327..3da5739eeb 100644 --- a/src/script/api/script_vehicle.cpp +++ b/src/script/api/script_vehicle.cpp @@ -72,7 +72,7 @@ EnforcePreconditionCustomError(VEHICLE_INVALID, !ScriptGameSettings::IsDisabledVehicleType((ScriptVehicle::VehicleType)type), ScriptVehicle::ERR_VEHICLE_BUILD_DISABLED); - if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, engine_id | (cargo << 24), 0, {})) return VEHICLE_INVALID; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, engine_id, true, cargo, INVALID_CLIENT_ID)) return VEHICLE_INVALID; /* In case of test-mode, we return VehicleID 0 */ return 0; @@ -94,7 +94,7 @@ if (!ScriptEngine::IsBuildable(engine_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; - CommandCost res = ::Command::Do(DC_QUERY_COST, depot, engine_id | (cargo << 24), 0, {}); + CommandCost res = ::Command::Do(DC_QUERY_COST, depot, engine_id, true, cargo, INVALID_CLIENT_ID); return res.Succeeded() ? _returned_refit_capacity : -1; } @@ -162,7 +162,7 @@ EnforcePrecondition(false, IsValidVehicle(vehicle_id)); const Vehicle *v = ::Vehicle::Get(vehicle_id); - return ScriptObject::Command::Do(0, vehicle_id | (v->type == VEH_TRAIN ? 1 : 0) << 20, 0, {}); + return ScriptObject::Command::Do(0, vehicle_id, v->type == VEH_TRAIN, false, INVALID_CLIENT_ID); } /* static */ bool ScriptVehicle::_SellWagonInternal(VehicleID vehicle_id, int wagon, bool sell_attached_wagons) @@ -174,7 +174,7 @@ const Train *v = ::Train::Get(vehicle_id); while (wagon-- > 0) v = v->GetNextUnit(); - return ScriptObject::Command::Do(0, v->index | (sell_attached_wagons ? 1 : 0) << 20, 0, {}); + return ScriptObject::Command::Do(0, v->index, sell_attached_wagons, false, INVALID_CLIENT_ID); } /* static */ bool ScriptVehicle::SellWagon(VehicleID vehicle_id, int wagon) diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 0e0bccce0f..2729030d31 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -841,11 +841,10 @@ void Ship::SetDestTile(TileIndex tile) * @param flags type of operation. * @param tile tile of the depot where ship is built. * @param e the engine to build. - * @param data unused. * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ -CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **ret) +CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **ret) { tile = GetShipDepotNorthTile(tile); if (flags & DC_EXEC) { diff --git a/src/ship_cmd.h b/src/ship_cmd.h index 8738f54207..b17885e371 100644 --- a/src/ship_cmd.h +++ b/src/ship_cmd.h @@ -14,6 +14,6 @@ #include "engine_type.h" #include "vehicle_type.h" -CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **v); +CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **v); #endif /* SHIP_CMD_H */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index a86e835bd3..d2517d65ba 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -718,11 +718,11 @@ static void AddRearEngineToMultiheadedTrain(Train *v) * @param flags type of operation. * @param tile tile of the depot where rail-vehicle is built. * @param e the engine to build. - * @param data bit 0 prevents any free cars from being added to the train. + * @param free_cars add any free cars to the train. * @param[out] ret the vehicle that has been built. * @return the cost of this operation or an error. */ -CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **ret) +CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, bool free_cars, Vehicle **ret) { const RailVehicleInfo *rvi = &e->u.rail; @@ -789,7 +789,7 @@ CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engin v->ConsistChanged(CCF_ARRANGE); UpdateTrainGroupID(v); - if (!HasBit(data, 0) && !(flags & DC_AUTOREPLACE)) { // check if the cars should be added to the new vehicle + if (free_cars && !(flags & DC_AUTOREPLACE)) { // check if the cars should be added to the new vehicle NormalizeTrainVehInDepot(v); } @@ -1357,18 +1357,16 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, u * Sell a (single) train wagon/engine. * @param flags type of operation * @param t the train wagon to sell - * @param data the selling mode - * - data = 0: only sell the single dragged wagon/engine (and any belonging rear-engines) - * - data = 1: sell the vehicle and all vehicles following it in the chain - * if the wagon is dragged, don't delete the possibly belonging rear-engine to some front + * @param sell_chain the selling mode + * - sell_chain = false: only sell the single dragged wagon/engine (and any belonging rear-engines) + * - sell_chain = true: sell the vehicle and all vehicles following it in the chain + * if the wagon is dragged, don't delete the possibly belonging rear-engine to some front + * @param backup_order make order backup? * @param user the user for the order backup. * @return the cost of this operation or an error */ -CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint32 user) +CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, bool sell_chain, bool backup_order, ClientID user) { - /* Sell a chain of vehicles or not? */ - bool sell_chain = HasBit(data, 0); - Train *v = Train::From(t)->GetFirstEnginePart(); Train *first = v->First(); @@ -1418,7 +1416,7 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3 /* Copy other important data from the front engine */ new_head->CopyVehicleConfigAndStatistics(first); GroupStatistics::CountVehicle(new_head, 1); // after copying over the profit - } else if (v->IsPrimaryVehicle() && data & (MAKE_ORDER_BACKUP_FLAG >> 20)) { + } else if (v->IsPrimaryVehicle() && backup_order) { OrderBackup::Backup(v, user); } diff --git a/src/train_cmd.h b/src/train_cmd.h index 7b286e9983..4a7e5036ec 100644 --- a/src/train_cmd.h +++ b/src/train_cmd.h @@ -14,8 +14,8 @@ #include "engine_type.h" #include "vehicle_type.h" -CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, uint16 data, Vehicle **v); -CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *v, uint16 data, uint32 user); +CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, bool free_cars, Vehicle **ret); +CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, bool sell_chain, bool backup_order, ClientID user); CommandProc CmdMoveRailVehicle; CommandProc CmdForceTrainProceed; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index aeaefe68f4..f25a3cdd3e 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -79,15 +79,13 @@ const StringID _send_to_depot_msg_table[] = { * Build a vehicle. * @param flags for command * @param tile tile of depot where the vehicle is built - * @param p1 various bitstuffed data - * bits 0-15: vehicle type being built. - * bits 16-23: vehicle type specific bits passed on to the vehicle build functions. - * bits 24-31: refit cargo type. - * @param p2 User - * @param text unused + * @param eid vehicle type being built. + * @param use_free_vehicles use free vehicles when building the vehicle. + * @param cargo refit cargo type. + * @param client_id User * @return the cost of this operation or an error */ -CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id) { /* Elementary check for valid location. */ if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return CMD_ERROR; @@ -95,11 +93,9 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint VehicleType type = GetDepotVehicleType(tile); /* Validate the engine type. */ - EngineID eid = GB(p1, 0, 16); if (!IsEngineBuildable(eid, type, _current_company)) return_cmd_error(STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE + type); /* Validate the cargo type. */ - CargoID cargo = GB(p1, 24, 8); if (cargo >= NUM_CARGO && cargo != CT_INVALID) return CMD_ERROR; const Engine *e = Engine::Get(eid); @@ -140,10 +136,10 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint Vehicle *v = nullptr; switch (type) { - case VEH_TRAIN: value.AddCost(CmdBuildRailVehicle(subflags, tile, e, GB(p1, 16, 8), &v)); break; - case VEH_ROAD: value.AddCost(CmdBuildRoadVehicle(subflags, tile, e, GB(p1, 16, 8), &v)); break; - case VEH_SHIP: value.AddCost(CmdBuildShip (subflags, tile, e, GB(p1, 16, 8), &v)); break; - case VEH_AIRCRAFT: value.AddCost(CmdBuildAircraft (subflags, tile, e, GB(p1, 16, 8), &v)); break; + case VEH_TRAIN: value.AddCost(CmdBuildRailVehicle(subflags, tile, e, use_free_vehicles, &v)); break; + case VEH_ROAD: value.AddCost(CmdBuildRoadVehicle(subflags, tile, e, &v)); break; + case VEH_SHIP: value.AddCost(CmdBuildShip (subflags, tile, e, &v)); break; + case VEH_AIRCRAFT: value.AddCost(CmdBuildAircraft (subflags, tile, e, &v)); break; default: NOT_REACHED(); // Safe due to IsDepotTile() } @@ -176,14 +172,14 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint if (v->IsPrimaryVehicle()) { GroupStatistics::CountVehicle(v, 1); - if (!(subflags & DC_AUTOREPLACE)) OrderBackup::Restore(v, p2); + if (!(subflags & DC_AUTOREPLACE)) OrderBackup::Restore(v, client_id); } } /* If we are not in DC_EXEC undo everything */ if (flags != subflags) { - Command::Do(DC_EXEC, 0, v->index, 0, {}); + Command::Do(DC_EXEC, 0, v->index, false, false, INVALID_CLIENT_ID); } } @@ -197,17 +193,16 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint * Sell a vehicle. * @param tile unused. * @param flags for command. - * @param p1 various bitstuffed data. - * bits 0-19: vehicle ID being sold. - * bits 20-30: vehicle type specific bits passed on to the vehicle build functions. - * bit 31: make a backup of the vehicle's order (if an engine). - * @param p2 User. + * @aram v_id vehicle ID being sold. + * @param sell_chain sell the vehicle and all vehicles following it in the chain. + * @param backup_order make a backup of the vehicle's order (if an engine). + * @param client_id User. * @param text unused. * @return the cost of this operation or an error. */ -CommandCost CmdSellVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSellVehicle(DoCommandFlag flags, TileIndex tile, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id) { - Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20)); + Vehicle *v = Vehicle::GetIfValid(v_id); if (v == nullptr) return CMD_ERROR; Vehicle *front = v->First(); @@ -220,22 +215,22 @@ CommandCost CmdSellVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 if (!front->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type); /* Can we actually make the order backup, i.e. are there enough orders? */ - if (p1 & MAKE_ORDER_BACKUP_FLAG && + if (backup_order && front->orders.list != nullptr && !front->orders.list->IsShared() && !Order::CanAllocateItem(front->orders.list->GetNumOrders())) { /* Only happens in exceptional cases when there aren't enough orders anyhow. * Thus it should be safe to just drop the orders in that case. */ - p1 &= ~MAKE_ORDER_BACKUP_FLAG; + backup_order = false; } if (v->type == VEH_TRAIN) { - ret = CmdSellRailWagon(flags, v, GB(p1, 20, 12), p2); + ret = CmdSellRailWagon(flags, v, sell_chain, backup_order, client_id); } else { ret = CommandCost(EXPENSES_NEW_VEHICLES, -front->value); if (flags & DC_EXEC) { - if (front->IsPrimaryVehicle() && p1 & MAKE_ORDER_BACKUP_FLAG) OrderBackup::Backup(front, p2); + if (front->IsPrimaryVehicle() && backup_order) OrderBackup::Backup(front, client_id); delete front; } } @@ -694,7 +689,7 @@ CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, uint32 CommandCost last_error = CMD_ERROR; bool had_success = false; for (uint i = 0; i < list.size(); i++) { - CommandCost ret = Command::Do(flags, tile, list[i]->index | (1 << 20), 0, {}); + CommandCost ret = Command::Do(flags, tile, list[i]->index, true, false, INVALID_CLIENT_ID); if (ret.Succeeded()) { cost.AddCost(ret); had_success = true; @@ -872,11 +867,11 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint DoCommandFlag build_flags = flags; if ((flags & DC_EXEC) && !v->IsPrimaryVehicle()) build_flags |= DC_AUTOREPLACE; - CommandCost cost = Command::Do(build_flags, tile, v->engine_type | (1 << 16) | (CT_INVALID << 24), 0, {}); + CommandCost cost = Command::Do(build_flags, tile, v->engine_type, false, CT_INVALID, INVALID_CLIENT_ID); if (cost.Failed()) { /* Can't build a part, then sell the stuff we already made; clear up the mess */ - if (w_front != nullptr) Command::Do(flags, w_front->tile, w_front->index | (1 << 20), 0, {}); + if (w_front != nullptr) Command::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID); return cost; } @@ -896,8 +891,8 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint if (result.Failed()) { /* The train can't be joined to make the same consist as the original. * Sell what we already made (clean up) and return an error. */ - Command::Do(flags, w_front->tile, w_front->index | 1 << 20, 0, {}); - Command::Do(flags, w_front->tile, w->index | 1 << 20, 0, {}); + Command::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID); + Command::Do(flags, w_front->tile, w->index, true, false, INVALID_CLIENT_ID); return result; // return error and the message returned from CMD_MOVE_RAIL_VEHICLE } } else { @@ -978,7 +973,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint CommandCost result = Command::Do(flags, 0, w_front->index | (p2 & 1 ? CO_SHARE : CO_COPY) << 30, v_front->index, {}); if (result.Failed()) { /* The vehicle has already been bought, so now it must be sold again. */ - Command::Do(flags, w_front->tile, w_front->index | 1 << 20, 0, {}); + Command::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID); return result; } @@ -989,7 +984,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint * check whether the company has enough money manually. */ if (!CheckCompanyHasMoney(total_cost)) { /* The vehicle has already been bought, so now it must be sold again. */ - Command::Do(flags, w_front->tile, w_front->index | 1 << 20, 0, {}); + Command::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID); return total_cost; } } diff --git a/src/vehicle_cmd.h b/src/vehicle_cmd.h index e6872e838b..98444033cc 100644 --- a/src/vehicle_cmd.h +++ b/src/vehicle_cmd.h @@ -12,8 +12,8 @@ #include "command_type.h" -CommandProc CmdBuildVehicle; -CommandProc CmdSellVehicle; +CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id); +CommandCost CmdSellVehicle(DoCommandFlag flags, TileIndex tile, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id); CommandProc CmdRefitVehicle; CommandProc CmdSendVehicleToDepot; CommandProc CmdChangeServiceInt; From de45a8729c0f1ab965e4adf4e6ad7095a4a678c8 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Fri, 5 Nov 2021 23:56:33 +0100 Subject: [PATCH 21/60] Codechange: Add DoCommand::Post specialization for commands that take no TileIndex. This adds a new Post overloads that still take a TileIndex which is used to place any error windows or text effects. --- src/command_func.h | 55 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/src/command_func.h b/src/command_func.h index e1f958f5bd..2a1c3dc37b 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -79,7 +79,7 @@ private: }; -template struct CommandHelper; +template struct CommandHelper; class CommandHelperBase { protected: @@ -100,7 +100,7 @@ protected: * @tparam Targs The command parameter types. */ template -struct CommandHelper : protected CommandHelperBase { +struct CommandHelper : protected CommandHelperBase { public: /** * This function executes a given command with the parameters from the #CommandProc parameter list. @@ -342,7 +342,56 @@ protected: } }; +/** + * Overload for #CommandHelper that exposes additional \c Post variants + * for commands that don't take a TileIndex themselves. + * @tparam Tcmd The command-id to execute. + * @tparam Targs The command parameter types. + */ +template +struct CommandHelper : CommandHelper +{ + /* Import Post overloads from our base class. */ + using CommandHelper::Post; + + /** + * Shortcut for Post when not using an error message. + * @param err_message Message prefix to show on error + * @param location Tile location for user feedback. + * @param args Parameters for the command + */ + static inline bool Post(StringID err_message, TileIndex location, Targs... args) { return Post(err_message, nullptr, location, std::forward(args)...); } + /** + * Shortcut for Post when not using a callback. + * @param callback A callback function to call after the command is finished + * @param location Tile location for user feedback. + * @param args Parameters for the command + */ + static inline bool Post(CommandCallback *callback, TileIndex location, Targs... args) { return Post((StringID)0, callback, location, std::forward(args)...); } + /** + * Shortcut for Post when not using a callback or an error message. + * @param location Tile location for user feedback. + * @param args Parameters for the command* + */ + static inline bool Post(TileIndex location, Targs... args) { return Post((StringID)0, nullptr, location, std::forward(args)...); } + + /** + * Post variant that takes a TileIndex (for error window location and text effects) for + * commands that don't take a TileIndex by themselves. + * @param err_message Message prefix to show on error + * @param callback A callback function to call after the command is finished + * @param location Tile location for user feedback. + * @param args Parameters for the command + * @return \c true if the command succeeded, else \c false. + */ + static inline bool Post(StringID err_message, CommandCallback *callback, TileIndex location, Targs... args) + { + return CommandHelper::InternalPost(err_message, callback, true, false, location, std::forward_as_tuple(args...)); + } +}; + + template -using Command = CommandHelper::ProcType>; +using Command = CommandHelper::ProcType, std::is_same_v::Args>>>; #endif /* COMMAND_FUNC_H */ From 211c630cbe4185a2adf8b8cd8f52ca58f8bf17ed Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Tue, 2 Nov 2021 22:58:40 +0100 Subject: [PATCH 22/60] Codechange: Un-bitstuff order commands. --- src/autoreplace_cmd.cpp | 2 +- src/order_backup.cpp | 2 +- src/order_base.h | 9 ++- src/order_cmd.cpp | 108 ++++++++++---------------------- src/order_cmd.h | 27 +++++--- src/order_gui.cpp | 41 ++++++------ src/order_type.h | 4 +- src/script/api/script_order.cpp | 40 ++++++------ src/vehicle_cmd.cpp | 2 +- src/vehicle_gui.cpp | 2 +- 10 files changed, 106 insertions(+), 131 deletions(-) diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 6a8937cb65..cda42643be 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -402,7 +402,7 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, CommandCost cost = CommandCost(); /* Share orders */ - if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command::Do(DC_EXEC, 0, new_head->index | CO_SHARE << 30, old_head->index, {})); + if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command::Do(DC_EXEC, CO_SHARE, new_head->index, old_head->index)); /* Copy group membership */ if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command::Do(DC_EXEC, 0, old_head->group_id, new_head->index, {})); diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 69ae6507db..1818029f22 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -75,7 +75,7 @@ void OrderBackup::DoRestore(Vehicle *v) { /* If we had shared orders, recover that */ if (this->clone != nullptr) { - Command::Do(DC_EXEC, 0, v->index | CO_SHARE << 30, this->clone->index, {}); + Command::Do(DC_EXEC, CO_SHARE, v->index, this->clone->index); } else if (this->orders != nullptr && OrderList::CanAllocateItem()) { v->orders.list = new OrderList(this->orders, v); this->orders = nullptr; diff --git a/src/order_base.h b/src/order_base.h index a722ef5d45..836ceb4b04 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -25,6 +25,9 @@ typedef Pool OrderListPool; extern OrderPool _order_pool; extern OrderListPool _orderlist_pool; +template +class EndianBufferWriter; + /* If you change this, keep in mind that it is saved on 3 places: * - Load_ORDR, all the global orders * - Vehicle -> current_order @@ -38,6 +41,10 @@ private: friend class SlVehicleCommon; friend class SlVehicleDisaster; + template + friend EndianBufferWriter &operator <<(EndianBufferWriter &buffer, const Order &data); + friend class EndianBufferReader &operator >>(class EndianBufferReader &buffer, Order &order); + uint8 type; ///< The type of order + non-stop flags uint8 flags; ///< Load/unload types, depot order/action types. DestinationID dest; ///< The destination of the order. @@ -51,7 +58,7 @@ private: public: Order *next; ///< Pointer to next order. If nullptr, end of list - Order() : flags(0), refit_cargo(CT_NO_REFIT), max_speed(UINT16_MAX) {} + Order() : flags(0), refit_cargo(CT_NO_REFIT), wait_time(0), travel_time(0), max_speed(UINT16_MAX) {} ~Order(); Order(uint32 packed); diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 45a0db99fe..66e79989a8 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -729,28 +729,25 @@ uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int /** * Add an order to the orderlist of a vehicle. * @param flags operation to perform - * @param tile unused * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 19) - ID of the vehicle - * - p1 = (bit 24 - 31) - the selected order (if any). If the last order is given, + * @param veh ID of the vehicle + * @param sel_ord the selected order (if any). If the last order is given, * the order will be inserted before that one * the maximum vehicle order id is 254. - * @param p2 packed order to insert - * @param text unused + * @param new_order order to insert * @return the cost of this operation or an error */ -CommandCost CmdInsertOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID sel_ord, const Order &new_order) { - VehicleID veh = GB(p1, 0, 20); - VehicleOrderID sel_ord = GB(p1, 20, 8); - Order new_order(p2); - Vehicle *v = Vehicle::GetIfValid(veh); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; + /* Validate properties we don't want to have different from default as they are set by other commands. */ + if (new_order.GetRefitCargo() != CT_NO_REFIT || new_order.GetWaitTime() != 0 || new_order.GetTravelTime() != 0 || new_order.GetMaxSpeed() != UINT16_MAX) return CMD_ERROR; + /* Check if the inserted order is to the correct destination (owner, type), * and has the correct flags if any */ switch (new_order.GetType()) { @@ -1008,17 +1005,12 @@ static CommandCost DecloneOrder(Vehicle *dst, DoCommandFlag flags) /** * Delete an order from the orderlist of a vehicle. * @param flags operation to perform - * @param tile unused - * @param p1 the ID of the vehicle - * @param p2 the order to delete (max 255) - * @param text unused + * @param veh_id the ID of the vehicle + * @param sel_ord the order to delete (max 255) * @return the cost of this operation or an error */ -CommandCost CmdDeleteOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDeleteOrder(DoCommandFlag flags, VehicleID veh_id, VehicleOrderID sel_ord) { - VehicleID veh_id = GB(p1, 0, 20); - VehicleOrderID sel_ord = GB(p2, 0, 8); - Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; @@ -1113,17 +1105,12 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord) /** * Goto order of order-list. * @param flags operation to perform - * @param tile unused - * @param p1 The ID of the vehicle which order is skipped - * @param p2 the selected order to which we want to skip - * @param text unused + * @param veh_id The ID of the vehicle which order is skipped + * @param sel_ord the selected order to which we want to skip * @return the cost of this operation or an error */ -CommandCost CmdSkipToOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSkipToOrder(DoCommandFlag flags, VehicleID veh_id, VehicleOrderID sel_ord) { - VehicleID veh_id = GB(p1, 0, 20); - VehicleOrderID sel_ord = GB(p2, 0, 8); - Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle() || sel_ord == v->cur_implicit_order_index || sel_ord >= v->GetNumOrders() || v->GetNumOrders() < 2) return CMD_ERROR; @@ -1150,22 +1137,15 @@ CommandCost CmdSkipToOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 /** * Move an order inside the orderlist * @param flags operation to perform - * @param tile unused - * @param p1 the ID of the vehicle - * @param p2 order to move and target - * bit 0-15 : the order to move - * bit 16-31 : the target order - * @param text unused + * @param veh the ID of the vehicle + * @param moving_order the order to move + * @param target_order the target order * @return the cost of this operation or an error * @note The target order will move one place down in the orderlist * if you move the order upwards else it'll move it one place down */ -CommandCost CmdMoveOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdMoveOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID moving_order, VehicleOrderID target_order) { - VehicleID veh = GB(p1, 0, 20); - VehicleOrderID moving_order = GB(p2, 0, 16); - VehicleOrderID target_order = GB(p2, 16, 16); - Vehicle *v = Vehicle::GetIfValid(veh); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; @@ -1251,25 +1231,16 @@ CommandCost CmdMoveOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /** * Modify an order in the orderlist of a vehicle. * @param flags operation to perform - * @param tile unused - * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 19) - ID of the vehicle - * - p1 = (bit 24 - 31) - the selected order (if any). If the last order is given, - * the order will be inserted before that one - * the maximum vehicle order id is 254. - * @param p2 various bitstuffed elements - * - p2 = (bit 0 - 3) - what data to modify (@see ModifyOrderFlags) - * - p2 = (bit 4 - 15) - the data to modify - * @param text unused + * @param veh ID of the vehicle + * @param sel_ord the selected order (if any). If the last order is given, + * the order will be inserted before that one + * the maximum vehicle order id is 254. + * @param mof what data to modify (@see ModifyOrderFlags) + * @param data the data to modify * @return the cost of this operation or an error */ -CommandCost CmdModifyOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdModifyOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID sel_ord, ModifyOrderFlags mof, uint16 data) { - VehicleOrderID sel_ord = GB(p1, 20, 8); - VehicleID veh = GB(p1, 0, 20); - ModifyOrderFlags mof = Extract(p2); - uint16 data = GB(p2, 4, 11); - if (mof >= MOF_END) return CMD_ERROR; Vehicle *v = Vehicle::GetIfValid(veh); @@ -1524,26 +1495,20 @@ static bool CheckAircraftOrderDistance(const Aircraft *v_new, const Vehicle *v_o /** * Clone/share/copy an order-list of another vehicle. * @param flags operation to perform - * @param tile unused - * @param p1 various bitstuffed elements - * - p1 = (bit 0-19) - destination vehicle to clone orders to - * - p1 = (bit 30-31) - action to perform - * @param p2 source vehicle to clone orders from, if any (none for CO_UNSHARE) - * @param text unused + * @param action action to perform + * @param veh_dst destination vehicle to clone orders to + * @param veh_src source vehicle to clone orders from, if any (none for CO_UNSHARE) * @return the cost of this operation or an error */ -CommandCost CmdCloneOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCloneOrder(DoCommandFlag flags, CloneOptions action, VehicleID veh_dst, VehicleID veh_src) { - VehicleID veh_src = GB(p2, 0, 20); - VehicleID veh_dst = GB(p1, 0, 20); - Vehicle *dst = Vehicle::GetIfValid(veh_dst); if (dst == nullptr || !dst->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(dst->owner); if (ret.Failed()) return ret; - switch (GB(p1, 30, 2)) { + switch (action) { case CO_SHARE: { Vehicle *src = Vehicle::GetIfValid(veh_src); @@ -1671,20 +1636,13 @@ CommandCost CmdCloneOrder(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /** * Add/remove refit orders from an order * @param flags operation to perform - * @param tile Not used - * @param p1 VehicleIndex of the vehicle having the order - * @param p2 bitmask - * - bit 0-7 CargoID - * - bit 16-23 number of order to modify - * @param text unused + * @param veh VehicleIndex of the vehicle having the order + * @param order_number number of order to modify + * @param cargo CargoID * @return the cost of this operation or an error */ -CommandCost CmdOrderRefit(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdOrderRefit(DoCommandFlag flags, VehicleID veh, VehicleOrderID order_number, CargoID cargo) { - VehicleID veh = GB(p1, 0, 20); - VehicleOrderID order_number = GB(p2, 16, 8); - CargoID cargo = GB(p2, 0, 8); - if (cargo >= NUM_CARGO && cargo != CT_NO_REFIT && cargo != CT_AUTO_REFIT) return CMD_ERROR; const Vehicle *v = Vehicle::GetIfValid(veh); diff --git a/src/order_cmd.h b/src/order_cmd.h index fa3424ce42..aeb42b6240 100644 --- a/src/order_cmd.h +++ b/src/order_cmd.h @@ -11,14 +11,16 @@ #define ORDER_CMD_H #include "command_type.h" +#include "order_base.h" +#include "misc/endian_buffer.hpp" -CommandProc CmdModifyOrder; -CommandProc CmdSkipToOrder; -CommandProc CmdDeleteOrder; -CommandProc CmdInsertOrder; -CommandProc CmdOrderRefit; -CommandProc CmdCloneOrder; -CommandProc CmdMoveOrder; +CommandCost CmdModifyOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID sel_ord, ModifyOrderFlags mof, uint16 data); +CommandCost CmdSkipToOrder(DoCommandFlag flags, VehicleID veh_id, VehicleOrderID sel_ord); +CommandCost CmdDeleteOrder(DoCommandFlag flags, VehicleID veh_id, VehicleOrderID sel_ord); +CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID sel_ord, const Order &new_order); +CommandCost CmdOrderRefit(DoCommandFlag flags, VehicleID veh, VehicleOrderID order_number, CargoID cargo); +CommandCost CmdCloneOrder(DoCommandFlag flags, CloneOptions action, VehicleID veh_dst, VehicleID veh_src); +CommandCost CmdMoveOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID moving_order, VehicleOrderID target_order); CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id); DEF_CMD_TRAIT(CMD_MODIFY_ORDER, CmdModifyOrder, 0, CMDT_ROUTE_MANAGEMENT) @@ -30,4 +32,15 @@ DEF_CMD_TRAIT(CMD_CLONE_ORDER, CmdCloneOrder, 0, CMDT_ DEF_CMD_TRAIT(CMD_MOVE_ORDER, CmdMoveOrder, 0, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_CLEAR_ORDER_BACKUP, CmdClearOrderBackup, CMD_CLIENT_ID, CMDT_SERVER_SETTING) +template +inline EndianBufferWriter &operator <<(EndianBufferWriter &buffer, const Order &order) +{ + return buffer << order.type << order.flags << order.dest << order.refit_cargo << order.wait_time << order.travel_time << order.max_speed; +} + +inline EndianBufferReader &operator >>(EndianBufferReader &buffer, Order &order) +{ + return buffer >> order.type >> order.flags >> order.dest >> order.refit_cargo >> order.wait_time >> order.travel_time >> order.max_speed; +} + #endif /* ORDER_CMD_H */ diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 50413c7352..982c8f7b29 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -30,6 +30,7 @@ #include "engine_func.h" #include "vehicle_func.h" #include "order_cmd.h" +#include "company_cmd.h" #include "widgets/order_widget.h" @@ -592,7 +593,7 @@ private: } if (order->GetLoadType() == load_type) return; // If we still match, do nothing - Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (load_type << 4), {}); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_LOAD, load_type); } /** @@ -607,7 +608,7 @@ private: if (order == nullptr) return; i = (order->GetDepotOrderType() & ODTFB_SERVICE) ? DA_ALWAYS_GO : DA_SERVICE; } - Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4), {}); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_DEPOT_ACTION, i); } /** @@ -622,7 +623,7 @@ private: _settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); order.SetDepotActionType(ODATFB_NEAREST_DEPOT); - Command::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), {}); + Command::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), order); } /** @@ -642,11 +643,11 @@ private: } if (order->GetUnloadType() == unload_type) return; // If we still match, do nothing - Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_UNLOAD | (unload_type << 4), {}); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_UNLOAD, unload_type); /* Transfer and unload orders with leave empty as default */ if (unload_type == OUFB_TRANSFER || unload_type == OUFB_UNLOAD) { - Command::Post(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_LOAD | (OLFB_NO_LOAD << 4), {}); + Command::Post(this->vehicle->tile, this->vehicle->index, sel_ord, MOF_LOAD, OLFB_NO_LOAD); this->SetWidgetDirty(WID_O_FULL_LOAD); } } @@ -670,7 +671,7 @@ private: } this->SetWidgetDirty(WID_O_NON_STOP); - Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_NON_STOP | non_stop << 4, {}); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_NON_STOP, non_stop); } /** @@ -684,7 +685,7 @@ private: if (this->vehicle->GetNumOrders() <= 1) return; Command::Post(_ctrl_pressed ? STR_ERROR_CAN_T_SKIP_TO_ORDER : STR_ERROR_CAN_T_SKIP_ORDER, - this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders()), {}); + this->vehicle->tile, this->vehicle->index, _ctrl_pressed ? this->OrderGetSel() : ((this->vehicle->cur_implicit_order_index + 1) % this->vehicle->GetNumOrders())); } /** @@ -695,7 +696,7 @@ private: /* When networking, move one order lower */ int selected = this->selected_order + (int)_networking; - if (Command::Post(STR_ERROR_CAN_T_DELETE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), {})) { + if (Command::Post(STR_ERROR_CAN_T_DELETE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel())) { this->selected_order = selected >= this->vehicle->GetNumOrders() ? -1 : selected; this->UpdateButtonState(); } @@ -720,7 +721,7 @@ private: /* Get another vehicle that share orders with this vehicle. */ Vehicle *other_shared = (this->vehicle->FirstShared() == this->vehicle) ? this->vehicle->NextShared() : this->vehicle->PreviousShared(); /* Copy the order list of the other vehicle. */ - if (Command::Post(STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST, this->vehicle->tile, this->vehicle->index | CO_COPY << 30, other_shared->index, {})) { + if (Command::Post(STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST, this->vehicle->tile, CO_COPY, this->vehicle->index, other_shared->index)) { this->UpdateButtonState(); } } @@ -735,10 +736,10 @@ private: { if (_ctrl_pressed) { /* Cancel refitting */ - Command::Post(this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | (CT_NO_REFIT << 8) | CT_NO_REFIT, {}); + Command::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CT_NO_REFIT); } else { if (i == 1) { // Auto-refit to available cargo type. - Command::Post(this->vehicle->tile, this->vehicle->index, (this->OrderGetSel() << 16) | CT_AUTO_REFIT, {}); + Command::Post(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CT_AUTO_REFIT); } else { ShowVehicleRefitWindow(this->vehicle, this->OrderGetSel(), this, auto_refit); } @@ -1160,7 +1161,7 @@ public: order.index = 0; order.MakeConditional(order_id); - Command::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), {}); + Command::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), order); } ResetObjectToPlace(); break; @@ -1184,8 +1185,8 @@ public: } else if (sel == this->selected_order) { if (this->vehicle->type == VEH_TRAIN && sel < this->vehicle->GetNumOrders()) { Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, - this->vehicle->tile, this->vehicle->index + (sel << 20), - MOF_STOP_LOCATION | ((this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END) << 4, {}); + this->vehicle->tile, this->vehicle->index, sel, + MOF_STOP_LOCATION, (this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END); } } else { /* Select clicked order */ @@ -1332,7 +1333,7 @@ public: default: break; } - Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (sel << 20), MOF_COND_VALUE | Clamp(value, 0, 2047) << 4, {}); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel, MOF_COND_VALUE, Clamp(value, 0, 2047)); } } @@ -1370,11 +1371,11 @@ public: break; case WID_O_COND_VARIABLE: - Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_VARIABLE | index << 4, {}); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), MOF_COND_VARIABLE, index); break; case WID_O_COND_COMPARATOR: - Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), MOF_COND_COMPARATOR | index << 4, {}); + Command::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), MOF_COND_COMPARATOR, index); break; } } @@ -1387,7 +1388,7 @@ public: VehicleOrderID to_order = this->GetOrderFromPt(pt.y); if (!(from_order == to_order || from_order == INVALID_VEH_ORDER_ID || from_order > this->vehicle->GetNumOrders() || to_order == INVALID_VEH_ORDER_ID || to_order > this->vehicle->GetNumOrders()) && - Command::Post(STR_ERROR_CAN_T_MOVE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, from_order | (to_order << 16), {})) { + Command::Post(STR_ERROR_CAN_T_MOVE_THIS_ORDER, this->vehicle->tile, this->vehicle->index, from_order, to_order)) { this->selected_order = -1; this->UpdateButtonState(); } @@ -1439,7 +1440,7 @@ public: const Order cmd = GetOrderCmdFromTile(this->vehicle, tile); if (cmd.IsType(OT_NOTHING)) return; - if (Command::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack(), {})) { + if (Command::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), cmd)) { /* With quick goto the Go To button stays active */ if (!_settings_client.gui.quick_goto) ResetObjectToPlace(); } @@ -1457,7 +1458,7 @@ public: if (this->vehicle->GetNumOrders() != 0 && !share_order) return false; if (Command::Post(share_order ? STR_ERROR_CAN_T_SHARE_ORDER_LIST : STR_ERROR_CAN_T_COPY_ORDER_LIST, - this->vehicle->tile, this->vehicle->index | (share_order ? CO_SHARE : CO_COPY) << 30, v->index, {})) { + this->vehicle->tile, share_order ? CO_SHARE : CO_COPY, this->vehicle->index, v->index)) { this->selected_order = -1; ResetObjectToPlace(); } diff --git a/src/order_type.h b/src/order_type.h index 9f4d0ba22b..6743529078 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -140,7 +140,7 @@ enum OrderConditionComparator { /** * Enumeration for the data to set in #CmdModifyOrder. */ -enum ModifyOrderFlags { +enum ModifyOrderFlags : byte { MOF_NON_STOP, ///< Passes an OrderNonStopFlags. MOF_STOP_LOCATION, ///< Passes an OrderStopLocation. MOF_UNLOAD, ///< Passes an OrderUnloadType. @@ -177,7 +177,7 @@ template <> struct EnumPropsT : MakeEnumPropsT::Do(0, vehicle_id | (order_position << 20), MOF_COND_DESTINATION | (jump_to << 4), {}); + return ScriptObject::Command::Do(0, vehicle_id, order_position, MOF_COND_DESTINATION, jump_to); } /* static */ bool ScriptOrder::SetOrderCondition(VehicleID vehicle_id, OrderPosition order_position, OrderCondition condition) @@ -390,7 +390,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, condition >= OC_LOAD_PERCENTAGE && condition <= OC_REMAINING_LIFETIME); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), MOF_COND_VARIABLE | (condition << 4), {}); + return ScriptObject::Command::Do(0, vehicle_id, order_pos, MOF_COND_VARIABLE, condition); } /* static */ bool ScriptOrder::SetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position, CompareFunction compare) @@ -400,7 +400,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, compare >= CF_EQUALS && compare <= CF_IS_FALSE); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), MOF_COND_COMPARATOR | (compare << 4), {}); + return ScriptObject::Command::Do(0, vehicle_id, order_pos, MOF_COND_COMPARATOR, compare); } /* static */ bool ScriptOrder::SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, int32 value) @@ -411,7 +411,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (GetOrderCondition(vehicle_id, order_position) == OC_MAX_SPEED) value = value * 10 / 16; int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), MOF_COND_VALUE | (value << 4), {}); + return ScriptObject::Command::Do(0, vehicle_id, order_pos, MOF_COND_VALUE, value); } /* static */ bool ScriptOrder::SetStopLocation(VehicleID vehicle_id, OrderPosition order_position, StopLocation stop_location) @@ -424,9 +424,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - uint32 p1 = vehicle_id | (order_pos << 20); - uint32 p2 = MOF_STOP_LOCATION | (stop_location << 4); - return ScriptObject::Command::Do(0, p1, p2, {}); + return ScriptObject::Command::Do(0, vehicle_id, order_pos, MOF_STOP_LOCATION, stop_location); } /* static */ bool ScriptOrder::SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoID refit_cargo) @@ -435,9 +433,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, IsGotoStationOrder(vehicle_id, order_position) || (IsGotoDepotOrder(vehicle_id, order_position) && refit_cargo != CT_AUTO_REFIT)); EnforcePrecondition(false, ScriptCargo::IsValidCargo(refit_cargo) || refit_cargo == CT_AUTO_REFIT || refit_cargo == CT_NO_REFIT); - uint32 p1 = vehicle_id; - uint32 p2 = refit_cargo | ScriptOrderPositionToRealOrderPosition(vehicle_id, ScriptOrder::ResolveOrderPosition(vehicle_id, order_position)) << 16; - return ScriptObject::Command::Do(0, p1, p2, {}); + return ScriptObject::Command::Do(0, vehicle_id, ScriptOrderPositionToRealOrderPosition(vehicle_id, ScriptOrder::ResolveOrderPosition(vehicle_id, order_position)), refit_cargo); } /* static */ bool ScriptOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, ScriptOrderFlags order_flags) @@ -507,7 +503,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr order.SetNonStopType((OrderNonStopFlags)GB(order_flags, 0, 2)); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), order.Pack(), {}); + return ScriptObject::Command::Do(0, vehicle_id, order_pos, order); } /* static */ bool ScriptOrder::InsertConditionalOrder(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to) @@ -523,7 +519,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr order.MakeConditional(jump_to); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::Command::Do(0, vehicle_id | (order_pos << 20), order.Pack(), {}); + return ScriptObject::Command::Do(0, vehicle_id, order_pos, order); } /* static */ bool ScriptOrder::RemoveOrder(VehicleID vehicle_id, OrderPosition order_position) @@ -533,7 +529,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); - return ScriptObject::Command::Do(0, vehicle_id, order_pos, {}); + return ScriptObject::Command::Do(0, vehicle_id, order_pos); } /* static */ bool ScriptOrder::SkipToOrder(VehicleID vehicle_id, OrderPosition next_order) @@ -543,7 +539,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, next_order)); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, next_order); - return ScriptObject::Command::Do(0, vehicle_id, order_pos, {}); + return ScriptObject::Command::Do(0, vehicle_id, order_pos); } /** @@ -587,7 +583,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) EnforcePrecondition(false, (order_flags & OF_GOTO_NEAREST_DEPOT) == (current & OF_GOTO_NEAREST_DEPOT)); if ((current & OF_NON_STOP_FLAGS) != (order_flags & OF_NON_STOP_FLAGS)) { - return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, 0, vehicle_id | (order_pos << 20), (order_flags & OF_NON_STOP_FLAGS) << 4 | MOF_NON_STOP, {}); + return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, vehicle_id, order_pos, MOF_NON_STOP, order_flags & OF_NON_STOP_FLAGS); } switch (order->GetType()) { @@ -596,16 +592,16 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) uint data = DA_ALWAYS_GO; if (order_flags & OF_SERVICE_IF_NEEDED) data = DA_SERVICE; if (order_flags & OF_STOP_IN_DEPOT) data = DA_STOP; - return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, 0, vehicle_id | (order_pos << 20), (data << 4) | MOF_DEPOT_ACTION, {}); + return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, vehicle_id, order_pos, MOF_DEPOT_ACTION, data); } break; case OT_GOTO_STATION: if ((current & OF_UNLOAD_FLAGS) != (order_flags & OF_UNLOAD_FLAGS)) { - return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, 0, vehicle_id | (order_pos << 20), (order_flags & OF_UNLOAD_FLAGS) << 2 | MOF_UNLOAD, {}); + return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, vehicle_id, order_pos, MOF_UNLOAD, (order_flags & OF_UNLOAD_FLAGS) >> 2); } if ((current & OF_LOAD_FLAGS) != (order_flags & OF_LOAD_FLAGS)) { - return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, 0, vehicle_id | (order_pos << 20), (order_flags & OF_LOAD_FLAGS) >> 1 | MOF_LOAD, {}); + return ScriptObject::Command::Do(&::_DoCommandReturnSetOrderFlags, vehicle_id, order_pos, MOF_LOAD, (order_flags & OF_LOAD_FLAGS) >> 5); } break; @@ -639,7 +635,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) int order_pos_move = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position_move); int order_pos_target = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position_target); - return ScriptObject::Command::Do(0, vehicle_id, order_pos_move | (order_pos_target << 16), {}); + return ScriptObject::Command::Do(0, vehicle_id, order_pos_move, order_pos_target); } /* static */ bool ScriptOrder::CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id) @@ -647,7 +643,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(main_vehicle_id)); - return ScriptObject::Command::Do(0, vehicle_id | CO_COPY << 30, main_vehicle_id, {}); + return ScriptObject::Command::Do(0, CO_COPY, vehicle_id, main_vehicle_id); } /* static */ bool ScriptOrder::ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id) @@ -655,14 +651,14 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(main_vehicle_id)); - return ScriptObject::Command::Do(0, vehicle_id | CO_SHARE << 30, main_vehicle_id, {}); + return ScriptObject::Command::Do(0, CO_SHARE, vehicle_id, main_vehicle_id); } /* static */ bool ScriptOrder::UnshareOrders(VehicleID vehicle_id) { EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); - return ScriptObject::Command::Do(0, vehicle_id | CO_UNSHARE << 30, 0, {}); + return ScriptObject::Command::Do(0, CO_UNSHARE, vehicle_id, 0); } /* static */ uint ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile) diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index f25a3cdd3e..3f4bd2a5a0 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -970,7 +970,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint * the vehicle refitted before doing this, otherwise the moved * cargo types might not match (passenger vs non-passenger) */ - CommandCost result = Command::Do(flags, 0, w_front->index | (p2 & 1 ? CO_SHARE : CO_COPY) << 30, v_front->index, {}); + CommandCost result = Command::Do(flags, (p2 & 1 ? CO_SHARE : CO_COPY), w_front->index, v_front->index); if (result.Failed()) { /* The vehicle has already been bought, so now it must be sold again. */ Command::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID); diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 80b75e7ce8..2b7446a5e8 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1040,7 +1040,7 @@ struct RefitWindow : public Window { bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX; if (Command::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16, {}) && delete_window) this->Close(); } else { - if (Command::Post(v->tile, v->index, this->cargo->cargo | this->order << 16, {})) this->Close(); + if (Command::Post(v->tile, v->index, this->order, this->cargo->cargo)) this->Close(); } } break; From 2637c06f88ed6f9dea55449883f42a62c30f19d8 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Thu, 4 Nov 2021 00:10:13 +0100 Subject: [PATCH 23/60] Codechange: Un-bitstuff timetable commands. --- src/date_gui.cpp | 11 ++++--- src/date_gui.h | 4 +-- src/order_type.h | 2 +- src/timetable_cmd.cpp | 68 ++++++++++++++----------------------------- src/timetable_cmd.h | 8 ++--- src/timetable_gui.cpp | 33 +++++++++------------ 6 files changed, 50 insertions(+), 76 deletions(-) diff --git a/src/date_gui.cpp b/src/date_gui.cpp index 9327287201..66c9a378a3 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -24,6 +24,7 @@ /** Window to select a date graphically by using dropdowns */ struct SetDateWindow : Window { SetDateCallback *callback; ///< Callback to call when a date has been selected + void *callback_data; ///< Callback data pointer. YearMonthDay date; ///< The currently selected date Year min_year; ///< The minimum year in the year dropdown Year max_year; ///< The maximum year (inclusive) in the year dropdown @@ -38,9 +39,10 @@ struct SetDateWindow : Window { * @param max_year the maximum year (inclusive) to show in the year dropdown * @param callback the callback to call once a date has been selected */ - SetDateWindow(WindowDesc *desc, WindowNumber window_number, Window *parent, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback) : + SetDateWindow(WindowDesc *desc, WindowNumber window_number, Window *parent, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback, void *callback_data) : Window(desc), callback(callback), + callback_data(callback_data), min_year(std::max(MIN_YEAR, min_year)), max_year(std::min(MAX_YEAR, max_year)) { @@ -146,7 +148,7 @@ struct SetDateWindow : Window { break; case WID_SD_SET_DATE: - if (this->callback != nullptr) this->callback(this, ConvertYMDToDate(this->date.year, this->date.month, this->date.day)); + if (this->callback != nullptr) this->callback(this, ConvertYMDToDate(this->date.year, this->date.month, this->date.day), this->callback_data); this->Close(); break; } @@ -209,9 +211,10 @@ static WindowDesc _set_date_desc( * @param min_year the minimum year to show in the year dropdown * @param max_year the maximum year (inclusive) to show in the year dropdown * @param callback the callback to call once a date has been selected + * @param callback_data extra callback data */ -void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback) +void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback, void *callback_data) { CloseWindowByClass(WC_SET_DATE); - new SetDateWindow(&_set_date_desc, window_number, parent, initial_date, min_year, max_year, callback); + new SetDateWindow(&_set_date_desc, window_number, parent, initial_date, min_year, max_year, callback, callback_data); } diff --git a/src/date_gui.h b/src/date_gui.h index 8d41ee3e71..da866d01f5 100644 --- a/src/date_gui.h +++ b/src/date_gui.h @@ -18,8 +18,8 @@ * @param w the window that sends the callback * @param date the date that has been chosen */ -typedef void SetDateCallback(const Window *w, Date date); +typedef void SetDateCallback(const Window *w, Date date, void *data); -void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback); +void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback, void *callback_data); #endif /* DATE_GUI_H */ diff --git a/src/order_type.h b/src/order_type.h index 6743529078..1a0687794a 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -167,7 +167,7 @@ enum OrderDepotAction { /** * Enumeration for the data to set in #CmdChangeTimetable. */ -enum ModifyTimetableFlags { +enum ModifyTimetableFlags : byte { MTF_WAIT_TIME, ///< Set wait time. MTF_TRAVEL_TIME, ///< Set travel time. MTF_TRAVEL_SPEED, ///< Set max travel speed. diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index c889e5374f..3e5695b51a 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -87,32 +87,24 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, /** * Change timetable data of an order. * @param flags Operation to perform. - * @param tile Not used. - * @param p1 Various bitstuffed elements - * - p1 = (bit 0-19) - Vehicle with the orders to change. - * - p1 = (bit 20-27) - Order index to modify. - * - p1 = (bit 28-29) - Timetable data to change (@see ModifyTimetableFlags) - * @param p2 The amount of time to wait. - * - p2 = (bit 0-15) - The data to modify as specified by p1 bits 28-29. - * 0 to clear times, UINT16_MAX to clear speed limit. - * @param text unused + * @param veh Vehicle with the orders to change. + * @param order_number Order index to modify. + * @param mtf Timetable data to change (@see ModifyTimetableFlags) + * @param data The data to modify as specified by \c mtf. + * 0 to clear times, UINT16_MAX to clear speed limit. * @return the cost of this operation or an error */ -CommandCost CmdChangeTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeTimetable(DoCommandFlag flags, VehicleID veh, VehicleOrderID order_number, ModifyTimetableFlags mtf, uint16 data) { - VehicleID veh = GB(p1, 0, 20); - Vehicle *v = Vehicle::GetIfValid(veh); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; - VehicleOrderID order_number = GB(p1, 20, 8); Order *order = v->GetOrder(order_number); if (order == nullptr || order->IsType(OT_IMPLICIT)) return CMD_ERROR; - ModifyTimetableFlags mtf = Extract(p1); if (mtf >= MTF_END) return CMD_ERROR; int wait_time = order->GetWaitTime(); @@ -120,15 +112,15 @@ CommandCost CmdChangeTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, u int max_speed = order->GetMaxSpeed(); switch (mtf) { case MTF_WAIT_TIME: - wait_time = GB(p2, 0, 16); + wait_time = data; break; case MTF_TRAVEL_TIME: - travel_time = GB(p2, 0, 16); + travel_time = data; break; case MTF_TRAVEL_SPEED: - max_speed = GB(p2, 0, 16); + max_speed = data; if (max_speed == 0) max_speed = UINT16_MAX; // Disable speed limit. break; @@ -185,17 +177,11 @@ CommandCost CmdChangeTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, u /** * Clear the lateness counter to make the vehicle on time. * @param flags Operation to perform. - * @param tile Not used. - * @param p1 Various bitstuffed elements - * - p1 = (bit 0-19) - Vehicle with the orders to change. - * @param p2 unused - * @param text unused + * @param veh Vehicle with the orders to change. * @return the cost of this operation or an error */ -CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh) { - VehicleID veh = GB(p1, 0, 20); - Vehicle *v = Vehicle::GetIfValid(veh); if (v == nullptr || !v->IsPrimaryVehicle() || v->orders.list == nullptr) return CMD_ERROR; @@ -251,25 +237,20 @@ static bool VehicleTimetableSorter(Vehicle * const &a, Vehicle * const &b) /** * Set the start date of the timetable. * @param flags Operation to perform. - * @param tile Not used. - * @param p2 Various bitstuffed elements - * - p2 = (bit 0-19) - Vehicle ID. - * - p2 = (bit 20) - Set to 1 to set timetable start for all vehicles sharing this order - * @param p2 The timetable start date. - * @param text Not used. + * @param veh_id Vehicle ID. + * @param timetable_all Set to set timetable start for all vehicles sharing this order + * @param start_date The timetable start date. * @return The error or cost of the operation. */ -CommandCost CmdSetTimetableStart(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool timetable_all, Date start_date) { - bool timetable_all = HasBit(p1, 20); - Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20)); + Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle() || v->orders.list == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; /* Don't let a timetable start more than 15 years into the future or 1 year in the past. */ - Date start_date = (Date)p2; if (start_date < 0 || start_date > MAX_DAY) return CMD_ERROR; if (start_date - _date > 15 * DAYS_IN_LEAP_YEAR) return CMD_ERROR; if (_date - start_date > DAYS_IN_LEAP_YEAR) return CMD_ERROR; @@ -316,18 +297,13 @@ CommandCost CmdSetTimetableStart(DoCommandFlag flags, TileIndex tile, uint32 p1, * actually takes to complete it. When starting to autofill the current times * are cleared and the timetable will start again from scratch. * @param flags Operation to perform. - * @param tile Not used. - * @param p1 Vehicle index. - * @param p2 Various bitstuffed elements - * - p2 = (bit 0) - Set to 1 to enable, 0 to disable autofill. - * - p2 = (bit 1) - Set to 1 to preserve waiting times in non-destructive mode - * @param text unused + * @param veh Vehicle index. + * @param autofill Enable or disable autofill + * @param preserve_wait_time Set to preserve waiting times in non-destructive mode * @return the cost of this operation or an error */ -CommandCost CmdAutofillTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAutofillTimetable(DoCommandFlag flags, VehicleID veh, bool autofill, bool preserve_wait_time) { - VehicleID veh = GB(p1, 0, 20); - Vehicle *v = Vehicle::GetIfValid(veh); if (v == nullptr || !v->IsPrimaryVehicle() || v->orders.list == nullptr) return CMD_ERROR; @@ -335,7 +311,7 @@ CommandCost CmdAutofillTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, if (ret.Failed()) return ret; if (flags & DC_EXEC) { - if (HasBit(p2, 0)) { + if (autofill) { /* Start autofilling the timetable, which clears the * "timetable has started" bit. Times are not cleared anymore, but are * overwritten when the order is reached now. */ @@ -343,7 +319,7 @@ CommandCost CmdAutofillTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED); /* Overwrite waiting times only if they got longer */ - if (HasBit(p2, 1)) SetBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME); + if (preserve_wait_time) SetBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME); v->timetable_start = 0; v->lateness_counter = 0; diff --git a/src/timetable_cmd.h b/src/timetable_cmd.h index ba5e2b37e2..ddf1277372 100644 --- a/src/timetable_cmd.h +++ b/src/timetable_cmd.h @@ -12,10 +12,10 @@ #include "command_type.h" -CommandProc CmdChangeTimetable; -CommandProc CmdSetVehicleOnTime; -CommandProc CmdAutofillTimetable; -CommandProc CmdSetTimetableStart; +CommandCost CmdChangeTimetable(DoCommandFlag flags, VehicleID veh, VehicleOrderID order_number, ModifyTimetableFlags mtf, uint16 data); +CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh); +CommandCost CmdAutofillTimetable(DoCommandFlag flags, VehicleID veh, bool autofill, bool preserve_wait_time); +CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool timetable_all, Date start_date); DEF_CMD_TRAIT(CMD_CHANGE_TIMETABLE, CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_SET_VEHICLE_ON_TIME, CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT) diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 12c3914875..9a09bce365 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -23,6 +23,7 @@ #include "vehicle_gui.h" #include "settings_type.h" #include "timetable_cmd.h" +#include #include "widgets/timetable_widget.h" @@ -141,9 +142,9 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID * @param w the window related to the setting of the date * @param date the actually chosen date */ -static void ChangeTimetableStartCallback(const Window *w, Date date) +static void ChangeTimetableStartCallback(const Window *w, Date date, void *data) { - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, w->window_number, date, {}); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (VehicleID)w->window_number, reinterpret_cast(data) != 0, date); } @@ -502,14 +503,14 @@ struct TimetableWindow : Window { } } - static inline uint32 PackTimetableArgs(const Vehicle *v, uint selected, bool speed) + static inline std::tuple PackTimetableArgs(const Vehicle *v, uint selected, bool speed) { uint order_number = (selected + 1) / 2; ModifyTimetableFlags mtf = (selected % 2 == 1) ? (speed ? MTF_TRAVEL_SPEED : MTF_TRAVEL_TIME) : MTF_WAIT_TIME; if (order_number >= v->GetNumOrders()) order_number = 0; - return v->index | (order_number << 20) | (mtf << 28); + return { order_number, mtf }; } void OnClick(Point pt, int widget, int click_count) override @@ -530,7 +531,7 @@ struct TimetableWindow : Window { } case WID_VT_START_DATE: // Change the date that the timetable starts. - ShowSetDateWindow(this, v->index | (v->orders.list->IsCompleteTimetable() && _ctrl_pressed ? 1U << 20 : 0), _date, _cur_year, _cur_year + 15, ChangeTimetableStartCallback); + ShowSetDateWindow(this, v->index, _date, _cur_year, _cur_year + 15, ChangeTimetableStartCallback, reinterpret_cast(static_cast(v->orders.list->IsCompleteTimetable() && _ctrl_pressed))); break; case WID_VT_CHANGE_TIME: { // "Wait For" button. @@ -578,26 +579,23 @@ struct TimetableWindow : Window { } case WID_VT_CLEAR_TIME: { // Clear waiting time. - uint32 p1 = PackTimetableArgs(v, this->sel_index, false); - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, 0, {}); + auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, false); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, 0); break; } case WID_VT_CLEAR_SPEED: { // Clear max speed button. - uint32 p1 = PackTimetableArgs(v, this->sel_index, true); - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, UINT16_MAX, {}); + auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, true); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, UINT16_MAX); break; } case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter. - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, 0, {}); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index); break; case WID_VT_AUTOFILL: { // Autofill the timetable. - uint32 p2 = 0; - if (!HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(p2, 0); - if (_ctrl_pressed) SetBit(p2, 1); - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, p2, {}); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, !HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE), _ctrl_pressed); break; } @@ -619,8 +617,6 @@ struct TimetableWindow : Window { const Vehicle *v = this->vehicle; - uint32 p1 = PackTimetableArgs(v, this->sel_index, this->query_is_speed_query); - uint64 val = StrEmpty(str) ? 0 : strtoul(str, nullptr, 10); if (this->query_is_speed_query) { val = ConvertDisplaySpeedToKmhishSpeed(val); @@ -628,9 +624,8 @@ struct TimetableWindow : Window { if (!_settings_client.gui.timetable_in_ticks) val *= DAY_TICKS; } - uint32 p2 = std::min(val, UINT16_MAX); - - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, p2, {}); + auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, this->query_is_speed_query); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, std::min(val, UINT16_MAX)); } void OnResize() override From 21675ec7e22bfe53f20300cc27b4d50c84aeb4dc Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Fri, 5 Nov 2021 23:55:23 +0100 Subject: [PATCH 24/60] Codechange: Un-bitstuff vehicle/engine commands. --- src/aircraft_cmd.cpp | 6 +- src/autoreplace_cmd.cpp | 32 ++--- src/build_vehicle_gui.cpp | 4 +- src/core/enum_type.hpp | 6 +- src/depot_gui.cpp | 16 +-- src/economy.cpp | 6 +- src/engine.cpp | 45 +++---- src/engine_cmd.h | 8 +- src/engine_gui.cpp | 2 +- src/group_gui.cpp | 4 +- src/order_cmd.cpp | 2 +- src/roadveh_cmd.cpp | 9 +- src/roadveh_cmd.h | 2 +- src/script/api/script_engine.cpp | 4 +- src/script/api/script_event_types.cpp | 2 +- src/script/api/script_vehicle.cpp | 24 ++-- src/train_cmd.cpp | 46 +++---- src/train_cmd.h | 6 +- src/train_gui.cpp | 2 +- src/vehicle.cpp | 10 +- src/vehicle_cmd.cpp | 168 ++++++++++---------------- src/vehicle_cmd.h | 34 ++++-- src/vehicle_gui.cpp | 32 +++-- src/vehicle_type.h | 15 +-- src/vehiclelist.h | 4 +- 25 files changed, 221 insertions(+), 268 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index f1263f00cd..f0a50b012f 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1275,7 +1275,7 @@ void HandleMissingAircraftOrders(Aircraft *v) const Station *st = GetTargetAirportIfValid(v); if (st == nullptr) { Backup cur_company(_current_company, v->owner, FILE_LINE); - CommandCost ret = Command::Do(DC_EXEC, v->tile, v->index, 0, {}); + CommandCost ret = Command::Do(DC_EXEC, v->index, DepotCommand::None, {}); cur_company.Restore(); if (ret.Failed()) CrashAirplane(v); @@ -1638,7 +1638,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass /* Send the helicopter to a hangar if needed for replacement */ if (v->NeedsAutomaticServicing()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - Command::Do(DC_EXEC, v->tile, v->index | DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, 0, {}); + Command::Do(DC_EXEC, v->index, DepotCommand::Service | DepotCommand::LocateHangar, {}); cur_company.Restore(); } } @@ -1689,7 +1689,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc /* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */ if (v->NeedsAutomaticServicing()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - Command::Do(DC_EXEC, v->tile, v->index | DEPOT_SERVICE, 0, {}); + Command::Do(DC_EXEC, v->index, DepotCommand::Service, {}); cur_company.Restore(); } } diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index cda42643be..8338172b02 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -355,13 +355,13 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic if (refit_cargo != CT_NO_REFIT) { byte subtype = GetBestFittingSubType(old_veh, new_veh, refit_cargo); - cost.AddCost(Command::Do(DC_EXEC, 0, new_veh->index, refit_cargo | (subtype << 8), {})); + cost.AddCost(Command::Do(DC_EXEC, new_veh->index, refit_cargo, subtype, false, false, 0)); assert(cost.Succeeded()); // This should be ensured by GetNewCargoTypeForReplace() } /* Try to reverse the vehicle, but do not care if it fails as the new type might not be reversible */ if (new_veh->type == VEH_TRAIN && HasBit(Train::From(old_veh)->flags, VRF_REVERSE_DIRECTION)) { - Command::Do(DC_EXEC, 0, new_veh->index, true, {}); + Command::Do(DC_EXEC, new_veh->index, true); } return cost; @@ -373,9 +373,9 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic * @param evaluate_callback shall the start/stop callback be evaluated? * @return success or error */ -static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_callback) +static inline CommandCost DoCmdStartStopVehicle(const Vehicle *v, bool evaluate_callback) { - return Command::Do(DC_EXEC | DC_AUTOREPLACE, 0, v->index, evaluate_callback ? 1 : 0, {}); + return Command::Do(DC_EXEC | DC_AUTOREPLACE, v->index, evaluate_callback); } /** @@ -388,7 +388,7 @@ static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_ca */ static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlag flags, bool whole_chain) { - return Command::Do(flags | DC_NO_CARGO_CAP_CHECK, 0, v->index | (whole_chain ? 1 : 0) << 20, after != nullptr ? after->index : INVALID_VEHICLE, {}); + return Command::Do(flags | DC_NO_CARGO_CAP_CHECK, v->index, after != nullptr ? after->index : INVALID_VEHICLE, whole_chain); } /** @@ -411,10 +411,10 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, if (cost.Succeeded()) { /* Start the vehicle, might be denied by certain things */ assert((new_head->vehstatus & VS_STOPPED) != 0); - cost.AddCost(CmdStartStopVehicle(new_head, true)); + cost.AddCost(DoCmdStartStopVehicle(new_head, true)); /* Stop the vehicle again, but do not care about evil newgrfs allowing starting but not stopping :p */ - if (cost.Succeeded()) cost.AddCost(CmdStartStopVehicle(new_head, false)); + if (cost.Succeeded()) cost.AddCost(DoCmdStartStopVehicle(new_head, false)); } /* Last do those things which do never fail (resp. we do not care about), but which are not undo-able */ @@ -471,11 +471,11 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b } /* Sell the old vehicle */ - cost.AddCost(Command::Do(flags, 0, old_v->index, false, false, INVALID_CLIENT_ID)); + cost.AddCost(Command::Do(flags, old_v->index, false, false, INVALID_CLIENT_ID)); /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - Command::Do(DC_EXEC, 0, new_v->index, false, false, INVALID_CLIENT_ID); + Command::Do(DC_EXEC, new_v->index, false, false, INVALID_CLIENT_ID); } } @@ -602,7 +602,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON); /* Sell wagon */ - [[maybe_unused]] CommandCost ret = Command::Do(DC_EXEC, 0, wagon->index, false, false, INVALID_CLIENT_ID); + [[maybe_unused]] CommandCost ret = Command::Do(DC_EXEC, wagon->index, false, false, INVALID_CLIENT_ID); assert(ret.Succeeded()); new_vehs[i] = nullptr; @@ -634,7 +634,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Sell the vehicle. * Note: This might temporarily construct new trains, so use DC_AUTOREPLACE to prevent * it from failing due to engine limits. */ - cost.AddCost(Command::Do(flags | DC_AUTOREPLACE, 0, w->index, false, false, INVALID_CLIENT_ID)); + cost.AddCost(Command::Do(flags | DC_AUTOREPLACE, w->index, false, false, INVALID_CLIENT_ID)); if ((flags & DC_EXEC) != 0) { old_vehs[i] = nullptr; if (i == 0) old_head = nullptr; @@ -665,7 +665,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon if ((flags & DC_EXEC) == 0) { for (int i = num_units - 1; i >= 0; i--) { if (new_vehs[i] != nullptr) { - Command::Do(DC_EXEC, 0, new_vehs[i]->index, false, false, INVALID_CLIENT_ID); + Command::Do(DC_EXEC, new_vehs[i]->index, false, false, INVALID_CLIENT_ID); new_vehs[i] = nullptr; } } @@ -696,12 +696,12 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon } /* Sell the old vehicle */ - cost.AddCost(Command::Do(flags, 0, old_head->index, false, false, INVALID_CLIENT_ID)); + cost.AddCost(Command::Do(flags, old_head->index, false, false, INVALID_CLIENT_ID)); } /* If we are not in DC_EXEC undo everything */ if ((flags & DC_EXEC) == 0) { - Command::Do(DC_EXEC, 0, new_head->index, false, false, INVALID_CLIENT_ID); + Command::Do(DC_EXEC, new_head->index, false, false, INVALID_CLIENT_ID); } } } @@ -764,7 +764,7 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1 bool was_stopped = free_wagon || ((v->vehstatus & VS_STOPPED) != 0); /* Stop the vehicle */ - if (!was_stopped) cost.AddCost(CmdStartStopVehicle(v, true)); + if (!was_stopped) cost.AddCost(DoCmdStartStopVehicle(v, true)); if (cost.Failed()) return cost; assert(free_wagon || v->IsStoppedInDepot()); @@ -792,7 +792,7 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1 } /* Restart the vehicle */ - if (!was_stopped) cost.AddCost(CmdStartStopVehicle(v, false)); + if (!was_stopped) cost.AddCost(DoCmdStartStopVehicle(v, false)); } if (cost.Succeeded() && nothing_to_do) cost = CommandCost(STR_ERROR_AUTOREPLACE_NOTHING_TO_DO); diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index ef87699ef8..39f840f73b 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1461,7 +1461,7 @@ struct BuildVehicleWindow : Window { case WID_BV_SHOW_HIDE: { const Engine *e = (this->sel_engine == INVALID_ENGINE) ? nullptr : Engine::Get(this->sel_engine); if (e != nullptr) { - Command::Post(0, 0, this->sel_engine | (e->IsHidden(_current_company) ? 0 : (1u << 31)), {}); + Command::Post(this->sel_engine, !e->IsHidden(_current_company)); } break; } @@ -1637,7 +1637,7 @@ struct BuildVehicleWindow : Window { { if (str == nullptr) return; - Command::Post(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, 0, this->rename_engine, 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, this->rename_engine, str); } void OnDropdownSelect(int widget, int index) override diff --git a/src/core/enum_type.hpp b/src/core/enum_type.hpp index 72e23ba363..f094bae914 100644 --- a/src/core/enum_type.hpp +++ b/src/core/enum_type.hpp @@ -29,9 +29,9 @@ /** Operators to allow to work with enum as with type safe bit set in C++ */ # define DECLARE_ENUM_AS_BIT_SET(mask_t) \ - inline constexpr mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 | m2);} \ - inline constexpr mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 & m2);} \ - inline constexpr mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 ^ m2);} \ + inline constexpr mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 | (std::underlying_type::type)m2);} \ + inline constexpr mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 & (std::underlying_type::type)m2);} \ + inline constexpr mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 ^ (std::underlying_type::type)m2);} \ inline constexpr mask_t& operator |= (mask_t& m1, mask_t m2) {m1 = m1 | m2; return m1;} \ inline constexpr mask_t& operator &= (mask_t& m1, mask_t m2) {m1 = m1 & m2; return m1;} \ inline constexpr mask_t& operator ^= (mask_t& m1, mask_t m2) {m1 = m1 ^ m2; return m1;} \ diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 830bdbaeed..1b5929de7e 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -142,7 +142,7 @@ static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Veh if (wagon == v) return; - Command::Post(STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index, {}); + Command::Post(STR_ERROR_CAN_T_MOVE_VEHICLE, v->tile, v->index, wagon == nullptr ? INVALID_VEHICLE : wagon->index, _ctrl_pressed); } static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END]; ///< Cell size for vehicle images in the depot view. @@ -803,7 +803,7 @@ struct DepotWindow : Window { case WID_D_STOP_ALL: case WID_D_START_ALL: { VehicleListIdentifier vli(VL_DEPOT_LIST, this->type, this->owner); - Command::Post(this->window_number, (widget == WID_D_START_ALL ? (1 << 0) : 0), vli.Pack(), {}); + Command::Post(this->window_number, widget == WID_D_START_ALL, false, vli); break; } @@ -826,7 +826,7 @@ struct DepotWindow : Window { break; case WID_D_AUTOREPLACE: - Command::Post(this->window_number, this->type, 0, {}); + Command::Post(this->window_number, this->type); break; } @@ -905,10 +905,10 @@ struct DepotWindow : Window { { if (_ctrl_pressed) { /* Share-clone, do not open new viewport, and keep tool active */ - Command::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, 1, {}); + Command::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, this->window_number, v->index, true); } else { /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to change things on new vehicle) */ - if (Command::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, 0, {})) { + if (Command::Post(STR_ERROR_CAN_T_BUY_TRAIN + v->type, CcCloneVehicle, this->window_number, v->index, false)) { ResetObjectToPlace(); } } @@ -1002,7 +1002,7 @@ struct DepotWindow : Window { if (this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, &gdvp) == MODE_DRAG_VEHICLE && sel != INVALID_VEHICLE) { if (gdvp.wagon != nullptr && gdvp.wagon->index == sel && _ctrl_pressed) { - Command::Post(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true, {}); + Command::Post(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE, Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true); } else if (gdvp.wagon == nullptr || gdvp.wagon->index != sel) { this->vehicle_over = INVALID_VEHICLE; TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head); @@ -1090,8 +1090,8 @@ static void DepotSellAllConfirmationCallback(Window *win, bool confirmed) if (confirmed) { DepotWindow *w = (DepotWindow*)win; TileIndex tile = w->window_number; - byte vehtype = w->type; - Command::Post(tile, vehtype, 0, {}); + VehicleType vehtype = w->type; + Command::Post(tile, vehtype); } } diff --git a/src/economy.cpp b/src/economy.cpp index 8bf608a864..5c7c2cee51 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -451,7 +451,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) * However, do not rely on that behaviour. */ int interval = CompanyServiceInterval(new_company, v->type); - Command::Do(DC_EXEC | DC_BANKRUPT, v->tile, v->index, interval | (new_company->settings.vehicle.servint_ispercent << 17), {}); + Command::Do(DC_EXEC | DC_BANKRUPT, v->index, interval, false, new_company->settings.vehicle.servint_ispercent); } v->owner = new_owner; @@ -1488,7 +1488,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station if (st->goods[cid].cargo.HasCargoFor(next_station)) { /* Try to find out if auto-refitting would succeed. In case the refit is allowed, * the returned refit capacity will be greater than zero. */ - Command::Do(DC_QUERY_COST, v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16, {}); // Auto-refit and only this vehicle including artic parts. + Command::Do(DC_QUERY_COST, v_start->index, cid, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts. /* Try to balance different loadable cargoes between parts of the consist, so that * all of them can be loaded. Avoid a situation where all vehicles suddenly switch * to the first loadable cargo for which there is only one packet. If the capacities @@ -1511,7 +1511,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station * "via any station" before reserving. We rather produce some more "any station" cargo than * misrouting it. */ IterateVehicleParts(v_start, ReturnCargoAction(st, INVALID_STATION)); - CommandCost cost = Command::Do(DC_EXEC, v_start->tile, v_start->index, new_cid | 1U << 24 | 0xFF << 8 | 1U << 16, {}); // Auto-refit and only this vehicle including artic parts. + CommandCost cost = Command::Do(DC_EXEC, v_start->index, new_cid, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts. if (cost.Succeeded()) v->First()->profit_this_year -= cost.GetCost() << 8; } diff --git a/src/engine.cpp b/src/engine.cpp index e9bb6c494b..6d0b25fcc7 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -876,20 +876,18 @@ void ClearEnginesHiddenFlagOfCompany(CompanyID cid) /** * Set the visibility of an engine. * @param flags Operation to perform. - * @param tile Unused. - * @param p1 Unused. - * @param p2 Bit 31: 0=visible, 1=hidden, other bits for the #EngineID. - * @param text Unused. + * @param engine_id Engine id.. + * @param hide Set for hidden, unset for visible. * @return The cost of this operation or an error. */ -CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, EngineID engine_id, bool hide) { - Engine *e = Engine::GetIfValid(GB(p2, 0, 31)); + Engine *e = Engine::GetIfValid(engine_id); if (e == nullptr || _current_company >= MAX_COMPANIES) return CMD_ERROR; if (!IsEngineBuildable(e->index, e->type, _current_company)) return CMD_ERROR; if ((flags & DC_EXEC) != 0) { - SB(e->company_hidden, _current_company, 1, GB(p2, 31, 1)); + SB(e->company_hidden, _current_company, 1, hide ? 1 : 0); AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); } @@ -900,18 +898,15 @@ CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, TileIndex tile, uint32 * Accept an engine prototype. XXX - it is possible that the top-company * changes while you are waiting to accept the offer? Then it becomes invalid * @param flags operation to perform - * @param tile unused - * @param p1 engine-prototype offered - * @param p2 unused - * @param text unused + * @param engine_id engine-prototype offered * @return the cost of this operation or an error */ -CommandCost CmdWantEnginePreview(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdWantEnginePreview(DoCommandFlag flags, EngineID engine_id) { - Engine *e = Engine::GetIfValid(p1); + Engine *e = Engine::GetIfValid(engine_id); if (e == nullptr || !(e->flags & ENGINE_EXCLUSIVE_PREVIEW) || e->preview_company != _current_company) return CMD_ERROR; - if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_company); + if (flags & DC_EXEC) AcceptEnginePreview(engine_id, _current_company); return CommandCost(); } @@ -919,20 +914,14 @@ CommandCost CmdWantEnginePreview(DoCommandFlag flags, TileIndex tile, uint32 p1, /** * Allow or forbid a specific company to use an engine * @param flags operation to perform - * @param tile unused - * @param p1 engine id - * @param p2 various bitstuffed elements - * - p2 = (bit 0 - 7) - Company to allow/forbid the use of an engine. - * - p2 = (bit 31) - 0 to forbid, 1 to allow. - * @param text unused + * @param engine_id engine id + * @param company_id Company to allow/forbid the use of an engine. + * @param allow false to forbid, true to allow. * @return the cost of this operation or an error */ -CommandCost CmdEngineCtrl(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdEngineCtrl(DoCommandFlag flags, EngineID engine_id, CompanyID company_id, bool allow) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - EngineID engine_id = (EngineID)p1; - CompanyID company_id = (CompanyID)GB(p2, 0, 8); - bool allow = HasBit(p2, 31); if (!Engine::IsValidID(engine_id) || !Company::IsValidID(company_id)) return CMD_ERROR; @@ -1073,15 +1062,13 @@ static bool IsUniqueEngineName(const std::string &name) /** * Rename an engine. * @param flags operation to perform - * @param tile unused - * @param p1 engine ID to rename - * @param p2 unused + * @param engine_id engine ID to rename * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameEngine(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameEngine(DoCommandFlag flags, EngineID engine_id, const std::string &text) { - Engine *e = Engine::GetIfValid(p1); + Engine *e = Engine::GetIfValid(engine_id); if (e == nullptr) return CMD_ERROR; bool reset = text.empty(); diff --git a/src/engine_cmd.h b/src/engine_cmd.h index 3ed47e8051..4b90c61d8a 100644 --- a/src/engine_cmd.h +++ b/src/engine_cmd.h @@ -12,10 +12,10 @@ #include "command_type.h" -CommandProc CmdWantEnginePreview; -CommandProc CmdEngineCtrl; -CommandProc CmdRenameEngine; -CommandProc CmdSetVehicleVisibility; +CommandCost CmdWantEnginePreview(DoCommandFlag flags, EngineID engine_id); +CommandCost CmdEngineCtrl(DoCommandFlag flags, EngineID engine_id, CompanyID company_id, bool allow); +CommandCost CmdRenameEngine(DoCommandFlag flags, EngineID engine_id, const std::string &text); +CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, EngineID engine_id, bool hide); DEF_CMD_TRAIT(CMD_WANT_ENGINE_PREVIEW, CmdWantEnginePreview, 0, CMDT_VEHICLE_MANAGEMENT) DEF_CMD_TRAIT(CMD_ENGINE_CTRL, CmdEngineCtrl, CMD_DEITY, CMDT_VEHICLE_MANAGEMENT) diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index c3b9553a7e..a14bc2652c 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -126,7 +126,7 @@ struct EnginePreviewWindow : Window { { switch (widget) { case WID_EP_YES: - Command::Post(0, this->window_number, 0, {}); + Command::Post(this->window_number); FALLTHROUGH; case WID_EP_NO: if (!_shift_pressed) this->Close(); diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 22f2889712..d3d270f314 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -802,7 +802,7 @@ public: case WID_GL_START_ALL: case WID_GL_STOP_ALL: { // Start/stop all vehicles of the list - Command::Post(0, (1 << 1) | (widget == WID_GL_START_ALL ? (1 << 0) : 0), this->vli.Pack(), {}); + Command::Post(0, widget == WID_GL_START_ALL, true, this->vli); break; } @@ -954,7 +954,7 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: { // Send to Depots - Command::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : 0U), this->vli.Pack(), {}); + Command::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DepotCommand::MassSend | (index == ADI_SERVICE ? DepotCommand::Service : DepotCommand::None), this->vli); break; } diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 66e79989a8..450de5681a 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1996,7 +1996,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool v->current_order.MakeGoToDepot(destination, v->current_order.GetDepotOrderType(), v->current_order.GetNonStopType(), (OrderDepotActionFlags)(v->current_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT), v->current_order.GetRefitCargo()); /* If there is no depot in front, reverse automatically (trains only) */ - if (v->type == VEH_TRAIN && reverse) Command::Do(DC_EXEC, v->tile, v->index, 0, {}); + if (v->type == VEH_TRAIN && reverse) Command::Do(DC_EXEC, v->index, false); if (v->type == VEH_AIRCRAFT) { Aircraft *a = Aircraft::From(v); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index a6442430e0..0b8d9deff8 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -361,15 +361,12 @@ bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destinati /** * Turn a roadvehicle around. * @param flags operation to perform - * @param tile unused - * @param p1 vehicle ID to turn - * @param p2 unused - * @param text unused + * @param veh_id vehicle ID to turn * @return the cost of this operation or an error */ -CommandCost CmdTurnRoadVeh(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id) { - RoadVehicle *v = RoadVehicle::GetIfValid(p1); + RoadVehicle *v = RoadVehicle::GetIfValid(veh_id); if (v == nullptr) return CMD_ERROR; if (!v->IsPrimaryVehicle()) return CMD_ERROR; diff --git a/src/roadveh_cmd.h b/src/roadveh_cmd.h index 94aaee743f..3d71abce73 100644 --- a/src/roadveh_cmd.h +++ b/src/roadveh_cmd.h @@ -16,7 +16,7 @@ CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **v); -CommandProc CmdTurnRoadVeh; +CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id); DEF_CMD_TRAIT(CMD_TURN_ROADVEH, CmdTurnRoadVeh, 0, CMDT_VEHICLE_MANAGEMENT) diff --git a/src/script/api/script_engine.cpp b/src/script/api/script_engine.cpp index d6cab36b6c..7530693d07 100644 --- a/src/script/api/script_engine.cpp +++ b/src/script/api/script_engine.cpp @@ -286,7 +286,7 @@ EnforcePrecondition(false, IsValidEngine(engine_id)); EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); - return ScriptObject::Command::Do(0, engine_id, (uint32)company | (1 << 31), {}); + return ScriptObject::Command::Do(engine_id, (::CompanyID)company, true); } /* static */ bool ScriptEngine::DisableForCompany(EngineID engine_id, ScriptCompany::CompanyID company) @@ -297,5 +297,5 @@ EnforcePrecondition(false, IsValidEngine(engine_id)); EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); - return ScriptObject::Command::Do(0, engine_id, company, {}); + return ScriptObject::Command::Do(engine_id, (::CompanyID)company, false); } diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp index f7776c40e8..e876febc28 100644 --- a/src/script/api/script_event_types.cpp +++ b/src/script/api/script_event_types.cpp @@ -112,7 +112,7 @@ int32 ScriptEventEnginePreview::GetVehicleType() bool ScriptEventEnginePreview::AcceptPreview() { if (!this->IsEngineValid()) return false; - return ScriptObject::Command::Do(0, this->engine, 0, {}); + return ScriptObject::Command::Do(this->engine); } bool ScriptEventCompanyAskMerger::AcceptMerger() diff --git a/src/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp index 3da5739eeb..c925026616 100644 --- a/src/script/api/script_vehicle.cpp +++ b/src/script/api/script_vehicle.cpp @@ -103,7 +103,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, vehicle_id, share_orders, {})) return VEHICLE_INVALID; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, vehicle_id, share_orders)) return VEHICLE_INVALID; /* In case of test-mode, we return VehicleID 0 */ return 0; @@ -125,7 +125,7 @@ while (dest_wagon-- > 0) w = w->GetNextUnit(); } - return ScriptObject::Command::Do(0, v->index | (move_attached_wagons ? 1 : 0) << 20, w == nullptr ? ::INVALID_VEHICLE : w->index, {}); + return ScriptObject::Command::Do(v->index, w == nullptr ? ::INVALID_VEHICLE : w->index, move_attached_wagons); } /* static */ bool ScriptVehicle::MoveWagon(VehicleID source_vehicle_id, int source_wagon, int dest_vehicle_id, int dest_wagon) @@ -143,7 +143,7 @@ if (!IsValidVehicle(vehicle_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; - CommandCost res = ::Command::Do(DC_QUERY_COST, 0, vehicle_id, cargo, {}); + CommandCost res = ::Command::Do(DC_QUERY_COST, vehicle_id, cargo, 0, false, false, 0); return res.Succeeded() ? _returned_refit_capacity : -1; } @@ -152,7 +152,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id) && ScriptCargo::IsValidCargo(cargo)); - return ScriptObject::Command::Do(0, vehicle_id, cargo, {}); + return ScriptObject::Command::Do(vehicle_id, cargo, 0, false, false, 0); } @@ -162,7 +162,7 @@ EnforcePrecondition(false, IsValidVehicle(vehicle_id)); const Vehicle *v = ::Vehicle::Get(vehicle_id); - return ScriptObject::Command::Do(0, vehicle_id, v->type == VEH_TRAIN, false, INVALID_CLIENT_ID); + return ScriptObject::Command::Do(vehicle_id, v->type == VEH_TRAIN, false, INVALID_CLIENT_ID); } /* static */ bool ScriptVehicle::_SellWagonInternal(VehicleID vehicle_id, int wagon, bool sell_attached_wagons) @@ -174,7 +174,7 @@ const Train *v = ::Train::Get(vehicle_id); while (wagon-- > 0) v = v->GetNextUnit(); - return ScriptObject::Command::Do(0, v->index, sell_attached_wagons, false, INVALID_CLIENT_ID); + return ScriptObject::Command::Do(v->index, sell_attached_wagons, false, INVALID_CLIENT_ID); } /* static */ bool ScriptVehicle::SellWagon(VehicleID vehicle_id, int wagon) @@ -192,7 +192,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - return ScriptObject::Command::Do(0, vehicle_id, 0, {}); + return ScriptObject::Command::Do(vehicle_id, DepotCommand::None, {}); } /* static */ bool ScriptVehicle::SendVehicleToDepotForServicing(VehicleID vehicle_id) @@ -200,7 +200,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - return ScriptObject::Command::Do(0, vehicle_id | DEPOT_SERVICE, 0, {}); + return ScriptObject::Command::Do(vehicle_id, DepotCommand::Service, {}); } /* static */ bool ScriptVehicle::IsInDepot(VehicleID vehicle_id) @@ -220,7 +220,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - return ScriptObject::Command::Do(0, vehicle_id, 0, {}); + return ScriptObject::Command::Do(vehicle_id, false); } /* static */ bool ScriptVehicle::ReverseVehicle(VehicleID vehicle_id) @@ -230,8 +230,8 @@ EnforcePrecondition(false, ::Vehicle::Get(vehicle_id)->type == VEH_ROAD || ::Vehicle::Get(vehicle_id)->type == VEH_TRAIN); switch (::Vehicle::Get(vehicle_id)->type) { - case VEH_ROAD: return ScriptObject::Command::Do(0, vehicle_id, 0, {}); - case VEH_TRAIN: return ScriptObject::Command::Do(0, vehicle_id, 0, {}); + case VEH_ROAD: return ScriptObject::Command::Do(vehicle_id); + case VEH_TRAIN: return ScriptObject::Command::Do(vehicle_id, false); default: NOT_REACHED(); } } @@ -247,7 +247,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_VEHICLE_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::Command::Do(0, vehicle_id, 0, text); + return ScriptObject::Command::Do(vehicle_id, text); } /* static */ TileIndex ScriptVehicle::GetLocation(VehicleID vehicle_id) diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index d2517d65ba..8bfc332f65 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -656,7 +656,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlag flags, TileIndex tile, const w->engine_type == e->index && ///< Same type w->First() != v && ///< Don't connect to ourself !(w->vehstatus & VS_CRASHED)) { ///< Not crashed/flooded - if (Command::Do(DC_EXEC, 0, v->index | 1 << 20, w->Last()->index, {}).Succeeded()) { + if (Command::Do(DC_EXEC, v->index, w->Last()->index, true).Succeeded()) { break; } } @@ -672,7 +672,7 @@ static void NormalizeTrainVehInDepot(const Train *u) for (const Train *v : Train::Iterate()) { if (v->IsFreeWagon() && v->tile == u->tile && v->track == TRACK_BIT_DEPOT) { - if (Command::Do(DC_EXEC, 0, v->index | 1 << 20, u->index, {}).Failed()) { + if (Command::Do(DC_EXEC, v->index, u->index, true).Failed()) { break; } } @@ -1162,21 +1162,14 @@ static void NormaliseTrainHead(Train *head) * Move a rail vehicle around inside the depot. * @param flags type of operation * Note: DC_AUTOREPLACE is set when autoreplace tries to undo its modifications or moves vehicles to temporary locations inside the depot. - * @param tile unused - * @param p1 various bitstuffed elements - * - p1 (bit 0 - 19) source vehicle index - * - p1 (bit 20) move all vehicles following the source vehicle - * @param p2 what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line - * @param text unused + * @param src_veh source vehicle index + * @param dest_veh what wagon to put the source wagon AFTER, XXX - INVALID_VEHICLE to make a new line + * @param move_chain move all vehicles following the source vehicle * @return the cost of this operation or an error */ -CommandCost CmdMoveRailVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID dest_veh, bool move_chain) { - VehicleID s = GB(p1, 0, 20); - VehicleID d = GB(p2, 0, 20); - bool move_chain = HasBit(p1, 20); - - Train *src = Train::GetIfValid(s); + Train *src = Train::GetIfValid(src_veh); if (src == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(src->owner); @@ -1187,10 +1180,10 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, u /* if nothing is selected as destination, try and find a matching vehicle to drag to. */ Train *dst; - if (d == INVALID_VEHICLE) { + if (dest_veh == INVALID_VEHICLE) { dst = (src->IsEngine() || (flags & DC_AUTOREPLACE)) ? nullptr : FindGoodVehiclePos(src); } else { - dst = Train::GetIfValid(d); + dst = Train::GetIfValid(dest_veh); if (dst == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(dst->owner); @@ -1908,22 +1901,20 @@ void ReverseTrainDirection(Train *v) /** * Reverse train. - * @param tile unused * @param flags type of operation - * @param p1 train to reverse - * @param p2 if true, reverse a unit in a train (needs to be in a depot) - * @param text unused + * @param veh_id train to reverse + * @param reverse_single_veh if true, reverse a unit in a train (needs to be in a depot) * @return the cost of this operation or an error */ -CommandCost CmdReverseTrainDirection(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdReverseTrainDirection(DoCommandFlag flags, VehicleID veh_id, bool reverse_single_veh) { - Train *v = Train::GetIfValid(p1); + Train *v = Train::GetIfValid(veh_id); if (v == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; - if (p2 != 0) { + if (reverse_single_veh) { /* turn a single unit around */ if (v->IsMultiheaded() || HasBit(EngInfo(v->engine_type)->callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) { @@ -1982,15 +1973,12 @@ CommandCost CmdReverseTrainDirection(DoCommandFlag flags, TileIndex tile, uint32 /** * Force a train through a red signal * @param flags type of operation - * @param tile unused - * @param p1 train to ignore the red signal - * @param p2 unused - * @param text unused + * @param veh_id train to ignore the red signal * @return the cost of this operation or an error */ -CommandCost CmdForceTrainProceed(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdForceTrainProceed(DoCommandFlag flags, VehicleID veh_id) { - Train *t = Train::GetIfValid(p1); + Train *t = Train::GetIfValid(veh_id); if (t == nullptr) return CMD_ERROR; if (!t->IsPrimaryVehicle()) return CMD_ERROR; diff --git a/src/train_cmd.h b/src/train_cmd.h index 4a7e5036ec..5d75171607 100644 --- a/src/train_cmd.h +++ b/src/train_cmd.h @@ -17,9 +17,9 @@ CommandCost CmdBuildRailVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, bool free_cars, Vehicle **ret); CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, bool sell_chain, bool backup_order, ClientID user); -CommandProc CmdMoveRailVehicle; -CommandProc CmdForceTrainProceed; -CommandProc CmdReverseTrainDirection; +CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID dest_veh, bool move_chain); +CommandCost CmdForceTrainProceed(DoCommandFlag flags, VehicleID veh_id); +CommandCost CmdReverseTrainDirection(DoCommandFlag flags, VehicleID veh_id, bool reverse_single_veh); DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE, CmdMoveRailVehicle, 0, CMDT_VEHICLE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, 0, CMDT_VEHICLE_MANAGEMENT) diff --git a/src/train_gui.cpp b/src/train_gui.cpp index e41bdf6aca..268b5b40b8 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -43,7 +43,7 @@ void CcBuildWagon(Commands cmd, const CommandCost &result, TileIndex tile, const if (found != nullptr) { found = found->Last(); /* put the new wagon at the end of the loco. */ - Command::Post(0, _new_vehicle_id, found->index, {}); + Command::Post( _new_vehicle_id, found->index, false); InvalidateWindowClassesData(WC_TRAINS_LIST, 0); } } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index f09edc9095..9a66053d33 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1565,7 +1565,7 @@ void VehicleEnterDepot(Vehicle *v) if (v->current_order.IsRefit()) { Backup cur_company(_current_company, v->owner, FILE_LINE); - CommandCost cost = Command::Do(DC_EXEC, v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8, {}); + CommandCost cost = Command::Do(DC_EXEC, v->index, v->current_order.GetRefitCargo(), 0xFF, false, false, 0); cur_company.Restore(); if (cost.Failed()) { @@ -2397,7 +2397,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) if (this->current_order.IsType(OT_GOTO_DEPOT)) { bool halt_in_depot = (this->current_order.GetDepotActionType() & ODATFB_HALT) != 0; - if (!!(command & DEPOT_SERVICE) == halt_in_depot) { + if (((command & DepotCommand::Service) != DepotCommand::None) == halt_in_depot) { /* We called with a different DEPOT_SERVICE setting. * Now we change the setting to apply the new one and let the vehicle head for the same depot. * Note: the if is (true for requesting service == true for ordered to stop in depot) */ @@ -2409,7 +2409,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) return CommandCost(); } - if (command & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancellation of depot orders + if ((command & DepotCommand::DontCancel) != DepotCommand::None) return CMD_ERROR; // Requested no cancellation of depot orders if (flags & DC_EXEC) { /* If the orders to 'goto depot' are in the orders list (forced servicing), * then skip to the next order; effectively cancelling this forced service */ @@ -2442,12 +2442,12 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) this->SetDestTile(location); this->current_order.MakeGoToDepot(destination, ODTF_MANUAL); - if (!(command & DEPOT_SERVICE)) this->current_order.SetDepotActionType(ODATFB_HALT); + if ((command & DepotCommand::Service) == DepotCommand::None) this->current_order.SetDepotActionType(ODATFB_HALT); SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP); /* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */ if (this->type == VEH_TRAIN && (reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) { - Command::Do(DC_EXEC, this->tile, this->index, 0, {}); + Command::Do(DC_EXEC, this->index, false); } if (this->type == VEH_AIRCRAFT) { diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 3f4bd2a5a0..100b309f90 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -151,7 +151,7 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, b if (refitting) { /* Refit only one vehicle. If we purchased an engine, it may have gained free wagons. */ - value.AddCost(CmdRefitVehicle(flags, tile, v->index, cargo | (1 << 16), {})); + value.AddCost(CmdRefitVehicle(flags, v->index, cargo, 0, false, false, 1)); } else { /* Fill in non-refitted capacities */ _returned_refit_capacity = e->GetDisplayDefaultCapacity(&_returned_mail_refit_capacity); @@ -179,7 +179,7 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, b /* If we are not in DC_EXEC undo everything */ if (flags != subflags) { - Command::Do(DC_EXEC, 0, v->index, false, false, INVALID_CLIENT_ID); + Command::Do(DC_EXEC, v->index, false, false, INVALID_CLIENT_ID); } } @@ -191,7 +191,6 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, b /** * Sell a vehicle. - * @param tile unused. * @param flags for command. * @aram v_id vehicle ID being sold. * @param sell_chain sell the vehicle and all vehicles following it in the chain. @@ -200,7 +199,7 @@ CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, b * @param text unused. * @return the cost of this operation or an error. */ -CommandCost CmdSellVehicle(DoCommandFlag flags, TileIndex tile, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id) +CommandCost CmdSellVehicle(DoCommandFlag flags, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id) { Vehicle *v = Vehicle::GetIfValid(v_id); if (v == nullptr) return CMD_ERROR; @@ -450,21 +449,18 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, /** * Refits a vehicle to the specified cargo type. * @param flags type of operation - * @param tile unused - * @param p1 vehicle ID to refit - * @param p2 various bitstuffed elements - * - p2 = (bit 0-7) - New cargo type to refit to. - * - p2 = (bit 8-15) - New cargo subtype to refit to. 0xFF means to try keeping the same subtype according to GetBestFittingSubType(). - * - p2 = (bit 16-23) - Number of vehicles to refit (not counting articulated parts). Zero means all vehicles. - * Only used if "refit only this vehicle" is false. - * - p2 = (bit 24) - Automatic refitting. - * - p2 = (bit 25) - Refit only this vehicle. Used only for cloning vehicles. - * @param text unused + * @param veh_id vehicle ID to refit + * @param new_cid New cargo type to refit to. + * @param new_subtype New cargo subtype to refit to. 0xFF means to try keeping the same subtype according to GetBestFittingSubType(). + * @param auto_refit Automatic refitting. + * @param only_this Refit only this vehicle. Used only for cloning vehicles. + * @param num_vehicles Number of vehicles to refit (not counting articulated parts). Zero means all vehicles. + * Only used if "refit only this vehicle" is false. * @return the cost of this operation or an error */ -CommandCost CmdRefitVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRefitVehicle(DoCommandFlag flags, VehicleID veh_id, CargoID new_cid, byte new_subtype, bool auto_refit, bool only_this, uint8 num_vehicles) { - Vehicle *v = Vehicle::GetIfValid(p1); + Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr) return CMD_ERROR; /* Don't allow disasters and sparks and such to be refitted. @@ -476,7 +472,6 @@ CommandCost CmdRefitVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint CommandCost ret = CheckOwnership(front->owner); if (ret.Failed()) return ret; - bool auto_refit = HasBit(p2, 24); bool free_wagon = v->type == VEH_TRAIN && Train::From(front)->IsFreeWagon(); // used by autoreplace/renew /* Don't allow shadows and such to be refitted. */ @@ -493,13 +488,10 @@ CommandCost CmdRefitVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint if (front->vehstatus & VS_CRASHED) return_cmd_error(STR_ERROR_VEHICLE_IS_DESTROYED); /* Check cargo */ - CargoID new_cid = GB(p2, 0, 8); - byte new_subtype = GB(p2, 8, 8); if (new_cid >= NUM_CARGO) return CMD_ERROR; /* For ships and aircraft there is always only one. */ - bool only_this = HasBit(p2, 25) || front->type == VEH_SHIP || front->type == VEH_AIRCRAFT; - uint8 num_vehicles = GB(p2, 16, 8); + only_this |= front->type == VEH_SHIP || front->type == VEH_AIRCRAFT; CommandCost cost = RefitVehicle(v, only_this, num_vehicles, new_cid, new_subtype, flags, auto_refit); @@ -544,18 +536,16 @@ CommandCost CmdRefitVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint /** * Start/Stop a vehicle * @param flags type of operation - * @param tile unused - * @param p1 vehicle to start/stop, don't forget to change CcStartStopVehicle if you modify this! - * @param p2 bit 0: Shall the start/stop newgrf callback be evaluated (only valid with DC_AUTOREPLACE for network safety) - * @param text unused + * @param veh_id vehicle to start/stop, don't forget to change CcStartStopVehicle if you modify this! + * @param evaluate_startstop_cb Shall the start/stop newgrf callback be evaluated (only valid with DC_AUTOREPLACE for network safety) * @return the cost of this operation or an error */ -CommandCost CmdStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdStartStopVehicle(DoCommandFlag flags, VehicleID veh_id, bool evaluate_startstop_cb) { /* Disable the effect of p2 bit 0, when DC_AUTOREPLACE is not set */ - if ((flags & DC_AUTOREPLACE) == 0) SetBit(p2, 0); + if ((flags & DC_AUTOREPLACE) == 0) evaluate_startstop_cb = true; - Vehicle *v = Vehicle::GetIfValid(p1); + Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); @@ -583,7 +573,7 @@ CommandCost CmdStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, default: return CMD_ERROR; } - if (HasBit(p2, 0)) { + if (evaluate_startstop_cb) { /* Check if this vehicle can be started/stopped. Failure means 'allow'. */ uint16 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v); StringID error = STR_NULL; @@ -610,7 +600,7 @@ CommandCost CmdStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, } if (flags & DC_EXEC) { - if (v->IsStoppedInDepot() && (flags & DC_AUTOREPLACE) == 0) DeleteVehicleNews(p1, STR_NEWS_TRAIN_IS_WAITING + v->type); + if (v->IsStoppedInDepot() && (flags & DC_AUTOREPLACE) == 0) DeleteVehicleNews(veh_id, STR_NEWS_TRAIN_IS_WAITING + v->type); v->vehstatus ^= VS_STOPPED; if (v->type != VEH_TRAIN) v->cur_speed = 0; // trains can stop 'slowly' @@ -627,21 +617,16 @@ CommandCost CmdStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, * Starts or stops a lot of vehicles * @param flags type of operation * @param tile Tile of the depot where the vehicles are started/stopped (only used for depots) - * @param p1 bitmask - * - bit 0 set = start vehicles, unset = stop vehicles - * - bit 1 if set, then it's a vehicle list window, not a depot and Tile is ignored in this case - * @param p2 packed VehicleListIdentifier - * @param text unused + * @param do_start set = start vehicles, unset = stop vehicles + * @param vehicle_list_window if set, then it's a vehicle list window, not a depot and Tile is ignored in this case + * @param vli VehicleListIdentifier * @return the cost of this operation or an error */ -CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, bool do_start, bool vehicle_list_window, const VehicleListIdentifier &vli) { VehicleList list; - bool do_start = HasBit(p1, 0); - bool vehicle_list_window = HasBit(p1, 1); - VehicleListIdentifier vli; - if (!vli.UnpackIfValid(p2)) return CMD_ERROR; + if (!vli.Valid()) return CMD_ERROR; if (!IsCompanyBuildableVehicleType(vli.vtype)) return CMD_ERROR; if (vehicle_list_window) { @@ -659,7 +644,7 @@ CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 if (!vehicle_list_window && !v->IsChainInDepot()) continue; /* Just try and don't care if some vehicle's can't be stopped. */ - Command::Do(flags, tile, v->index, 0, {}); + Command::Do(flags, v->index, false); } return CommandCost(); @@ -669,17 +654,14 @@ CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, uint32 * Sells all vehicles in a depot * @param flags type of operation * @param tile Tile of the depot where the depot is - * @param p1 Vehicle type - * @param p2 unused - * @param text unused + * @param vehicle_type Vehicle type * @return the cost of this operation or an error */ -CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type) { VehicleList list; CommandCost cost(EXPENSES_NEW_VEHICLES); - VehicleType vehicle_type = Extract(p1); if (!IsCompanyBuildableVehicleType(vehicle_type)) return CMD_ERROR; @@ -689,7 +671,7 @@ CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, uint32 CommandCost last_error = CMD_ERROR; bool had_success = false; for (uint i = 0; i < list.size(); i++) { - CommandCost ret = Command::Do(flags, tile, list[i]->index, true, false, INVALID_CLIENT_ID); + CommandCost ret = Command::Do(flags, list[i]->index, true, false, INVALID_CLIENT_ID); if (ret.Succeeded()) { cost.AddCost(ret); had_success = true; @@ -705,16 +687,13 @@ CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, uint32 * Autoreplace all vehicles in the depot * @param flags type of operation * @param tile Tile of the depot where the vehicles are - * @param p1 Type of vehicle - * @param p2 unused - * @param text unused + * @param vehicle_type Type of vehicle * @return the cost of this operation or an error */ -CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type) { VehicleList list; CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES); - VehicleType vehicle_type = Extract(p1); if (!IsCompanyBuildableVehicleType(vehicle_type)) return CMD_ERROR; if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return CMD_ERROR; @@ -809,16 +788,15 @@ static void CloneVehicleName(const Vehicle *src, Vehicle *dst) * Clone a vehicle. If it is a train, it will clone all the cars too * @param flags type of operation * @param tile tile of the depot where the cloned vehicle is build - * @param p1 the original vehicle's index - * @param p2 1 = shared orders, else copied orders - * @param text unused + * @param veh_id the original vehicle's index + * @param share_orders shared orders, else copied orders * @return the cost of this operation or an error */ -CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, VehicleID veh_id, bool share_orders) { CommandCost total_cost(EXPENSES_NEW_VEHICLES); - Vehicle *v = Vehicle::GetIfValid(p1); + Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; Vehicle *v_front = v; Vehicle *w = nullptr; @@ -871,7 +849,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint if (cost.Failed()) { /* Can't build a part, then sell the stuff we already made; clear up the mess */ - if (w_front != nullptr) Command::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID); + if (w_front != nullptr) Command::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID); return cost; } @@ -887,12 +865,12 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint if (v->type == VEH_TRAIN && !v->IsFrontEngine()) { /* this s a train car * add this unit to the end of the train */ - CommandCost result = Command::Do(flags, 0, w->index | 1 << 20, w_rear->index, {}); + CommandCost result = Command::Do(flags, w->index, w_rear->index, true); if (result.Failed()) { /* The train can't be joined to make the same consist as the original. * Sell what we already made (clean up) and return an error. */ - Command::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID); - Command::Do(flags, w_front->tile, w->index, true, false, INVALID_CLIENT_ID); + Command::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID); + Command::Do(flags, w->index, true, false, INVALID_CLIENT_ID); return result; // return error and the message returned from CMD_MOVE_RAIL_VEHICLE } } else { @@ -935,7 +913,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint /* Find out what's the best sub type */ byte subtype = GetBestFittingSubType(v, w, v->cargo_type); if (w->cargo_type != v->cargo_type || w->cargo_subtype != subtype) { - CommandCost cost = Command::Do(flags, 0, w->index, v->cargo_type | 1U << 25 | (subtype << 8), {}); + CommandCost cost = Command::Do(flags, w->index, v->cargo_type, subtype, false, true, 0); if (cost.Succeeded()) total_cost.AddCost(cost); } @@ -970,10 +948,10 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint * the vehicle refitted before doing this, otherwise the moved * cargo types might not match (passenger vs non-passenger) */ - CommandCost result = Command::Do(flags, (p2 & 1 ? CO_SHARE : CO_COPY), w_front->index, v_front->index); + CommandCost result = Command::Do(flags, (share_orders ? CO_SHARE : CO_COPY), w_front->index, v_front->index); if (result.Failed()) { /* The vehicle has already been bought, so now it must be sold again. */ - Command::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID); + Command::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID); return result; } @@ -984,7 +962,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint * check whether the company has enough money manually. */ if (!CheckCompanyHasMoney(total_cost)) { /* The vehicle has already been bought, so now it must be sold again. */ - Command::Do(flags, w_front->tile, w_front->index, true, false, INVALID_CLIENT_ID); + Command::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID); return total_cost; } } @@ -1009,7 +987,7 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con bool had_success = false; for (uint i = 0; i < list.size(); i++) { const Vehicle *v = list[i]; - CommandCost ret = Command::Do(flags, v->tile, v->index | (service ? DEPOT_SERVICE : 0U) | DEPOT_DONT_CANCEL, 0, {}); + CommandCost ret = Command::Do(flags, v->index, (service ? DepotCommand::Service : DepotCommand::None) | DepotCommand::DontCancel, {}); if (ret.Succeeded()) { had_success = true; @@ -1028,42 +1006,36 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con /** * Send a vehicle to the depot. * @param flags for command type - * @param tile unused - * @param p1 bitmask - * - p1 0-20: bitvehicle ID to send to the depot - * - p1 bits 25-8 - DEPOT_ flags (see vehicle_type.h) - * @param p2 packed VehicleListIdentifier. - * @param text unused + * @param veh_id vehicle ID to send to the depot + * @param depot_cmd DEPOT_ flags (see vehicle_type.h) + * @param vli VehicleListIdentifier. * @return the cost of this operation or an error */ -CommandCost CmdSendVehicleToDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSendVehicleToDepot(DoCommandFlag flags, VehicleID veh_id, DepotCommand depot_cmd, const VehicleListIdentifier &vli) { - if (p1 & DEPOT_MASS_SEND) { + if ((depot_cmd & DepotCommand::MassSend) != DepotCommand::None) { /* Mass goto depot requested */ - VehicleListIdentifier vli; - if (!vli.UnpackIfValid(p2)) return CMD_ERROR; - return SendAllVehiclesToDepot(flags, (p1 & DEPOT_SERVICE) != 0, vli); + if (!vli.Valid()) return CMD_ERROR; + return SendAllVehiclesToDepot(flags, (depot_cmd & DepotCommand::Service) != DepotCommand::None, vli); } - Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20)); + Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr) return CMD_ERROR; if (!v->IsPrimaryVehicle()) return CMD_ERROR; - return v->SendToDepot(flags, (DepotCommand)(p1 & DEPOT_COMMAND_MASK)); + return v->SendToDepot(flags, depot_cmd); } /** * Give a custom name to your vehicle * @param flags type of operation - * @param tile unused - * @param p1 vehicle ID to name - * @param p2 unused + * @param veh_id vehicle ID to name * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameVehicle(DoCommandFlag flags, VehicleID veh_id, const std::string &text) { - Vehicle *v = Vehicle::GetIfValid(p1); + Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); @@ -1093,39 +1065,33 @@ CommandCost CmdRenameVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uin /** * Change the service interval of a vehicle * @param flags type of operation - * @param tile unused - * @param p1 vehicle ID that is being service-interval-changed - * @param p2 bitmask - * - p2 = (bit 0-15) - new service interval - * - p2 = (bit 16) - service interval is custom flag - * - p2 = (bit 17) - service interval is percentage flag - * @param text unused + * @param veh_id vehicle ID that is being service-interval-changed + * @param serv_int new service interval + * @param is_custom service interval is custom flag + * @param is_percent service interval is percentage flag * @return the cost of this operation or an error */ -CommandCost CmdChangeServiceInt(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeServiceInt(DoCommandFlag flags, VehicleID veh_id, uint16 serv_int, bool is_custom, bool is_percent) { - Vehicle *v = Vehicle::GetIfValid(p1); + Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; const Company *company = Company::Get(v->owner); - bool iscustom = HasBit(p2, 16); - bool ispercent = iscustom ? HasBit(p2, 17) : company->settings.vehicle.servint_ispercent; + is_percent = is_custom ? is_percent : company->settings.vehicle.servint_ispercent; - uint16 serv_int; - if (iscustom) { - serv_int = GB(p2, 0, 16); - if (serv_int != GetServiceIntervalClamped(serv_int, ispercent)) return CMD_ERROR; + if (is_custom) { + if (serv_int != GetServiceIntervalClamped(serv_int, is_percent)) return CMD_ERROR; } else { serv_int = CompanyServiceInterval(company, v->type); } if (flags & DC_EXEC) { v->SetServiceInterval(serv_int); - v->SetServiceIntervalIsCustom(iscustom); - v->SetServiceIntervalIsPercent(ispercent); + v->SetServiceIntervalIsCustom(is_custom); + v->SetServiceIntervalIsPercent(is_percent); SetWindowDirty(WC_VEHICLE_DETAILS, v->index); } diff --git a/src/vehicle_cmd.h b/src/vehicle_cmd.h index 98444033cc..b2ad082286 100644 --- a/src/vehicle_cmd.h +++ b/src/vehicle_cmd.h @@ -11,18 +11,21 @@ #define VEHICLE_CMD_H #include "command_type.h" +#include "engine_type.h" +#include "vehicle_type.h" +#include "vehiclelist.h" CommandCost CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id); -CommandCost CmdSellVehicle(DoCommandFlag flags, TileIndex tile, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id); -CommandProc CmdRefitVehicle; -CommandProc CmdSendVehicleToDepot; -CommandProc CmdChangeServiceInt; -CommandProc CmdRenameVehicle; -CommandProc CmdCloneVehicle; -CommandProc CmdStartStopVehicle; -CommandProc CmdMassStartStopVehicle; -CommandProc CmdDepotSellAllVehicles; -CommandProc CmdDepotMassAutoReplace; +CommandCost CmdSellVehicle(DoCommandFlag flags, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id); +CommandCost CmdRefitVehicle(DoCommandFlag flags, VehicleID veh_id, CargoID new_cid, byte new_subtype, bool auto_refit, bool only_this, uint8 num_vehicles); +CommandCost CmdSendVehicleToDepot(DoCommandFlag flags, VehicleID veh_id, DepotCommand depot_cmd, const VehicleListIdentifier &vli); +CommandCost CmdChangeServiceInt(DoCommandFlag flags, VehicleID veh_id, uint16 serv_int, bool is_custom, bool is_percent); +CommandCost CmdRenameVehicle(DoCommandFlag flags, VehicleID veh_id, const std::string &text); +CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, VehicleID veh_id, bool share_orders); +CommandCost CmdStartStopVehicle(DoCommandFlag flags, VehicleID veh_id, bool evaluate_startstop_cb); +CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, bool do_start, bool vehicle_list_window, const VehicleListIdentifier &vli); +CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type); +CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type); DEF_CMD_TRAIT(CMD_BUILD_VEHICLE, CmdBuildVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_SELL_VEHICLE, CmdSellVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION) @@ -39,4 +42,15 @@ DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, 0, CommandCallback CcBuildPrimaryVehicle; CommandCallback CcStartStopVehicle; +template +inline EndianBufferWriter &operator <<(EndianBufferWriter &buffer, const VehicleListIdentifier &vli) +{ + return buffer << vli.type << vli.vtype << vli.company << vli.index; +} + +inline EndianBufferReader &operator >>(EndianBufferReader &buffer, VehicleListIdentifier &vli) +{ + return buffer >> vli.type >> vli.vtype >> vli.company >> vli.index; +} + #endif /* VEHICLE_CMD_H */ diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 2b7446a5e8..289a821e56 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -776,9 +776,7 @@ struct RefitWindow : public Window { StringID GetCapacityString(RefitOption *option) const { assert(_current_company == _local_company); - Vehicle *v = Vehicle::Get(this->window_number); - CommandCost cost = Command::Do(DC_QUERY_COST, v->tile, this->selected_vehicle, option->cargo | - option->subtype << 8 | this->num_vehicles << 16 | (int)this->auto_refit << 24, {}); + CommandCost cost = Command::Do(DC_QUERY_COST, this->selected_vehicle, option->cargo, option->subtype, this->auto_refit, false, this->num_vehicles); if (cost.Failed()) return INVALID_STRING_ID; @@ -1038,7 +1036,7 @@ struct RefitWindow : public Window { if (this->order == INVALID_VEH_ORDER_ID) { bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX; - if (Command::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16, {}) && delete_window) this->Close(); + if (Command::Post(GetCmdRefitVehMsg(v), v->tile, this->selected_vehicle, this->cargo->cargo, this->cargo->subtype, false, false, this->num_vehicles) && delete_window) this->Close(); } else { if (Command::Post(v->tile, v->index, this->order, this->cargo->cargo)) this->Close(); } @@ -1899,7 +1897,7 @@ public: case WID_VL_STOP_ALL: case WID_VL_START_ALL: - Command::Post(0, (1 << 1) | (widget == WID_VL_START_ALL ? (1 << 0) : 0), this->window_number, {}); + Command::Post(0, widget == WID_VL_START_ALL, true, this->vli); break; } } @@ -1924,7 +1922,7 @@ public: break; case ADI_SERVICE: // Send for servicing case ADI_DEPOT: // Send to Depots - Command::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number, {}); + Command::Post(GetCmdSendToDepotMsg(this->vli.vtype), 0, DepotCommand::MassSend | (index == ADI_SERVICE ? DepotCommand::Service : DepotCommand::None), this->vli); break; default: NOT_REACHED(); @@ -2427,7 +2425,7 @@ struct VehicleDetailsWindow : Window { mod = GetServiceIntervalClamped(mod + v->GetServiceInterval(), v->ServiceIntervalIsPercent()); if (mod == v->GetServiceInterval()) return; - Command::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17), {}); + Command::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->index, mod, true, v->ServiceIntervalIsPercent()); break; } @@ -2463,7 +2461,7 @@ struct VehicleDetailsWindow : Window { bool iscustom = index != 0; bool ispercent = iscustom ? (index == 2) : Company::Get(v->owner)->settings.vehicle.servint_ispercent; uint16 interval = GetServiceIntervalClamped(v->GetServiceInterval(), ispercent); - Command::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17), {}); + Command::Post(STR_ERROR_CAN_T_CHANGE_SERVICING, v->index, interval, iscustom, ispercent); break; } } @@ -2628,8 +2626,8 @@ void CcStartStopVehicle(Commands cmd, const CommandCost &result, TileIndex tile, { if (result.Failed()) return; - auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); - const Vehicle *v = Vehicle::GetIfValid(p1); + VehicleID veh_id = std::get<0>(EndianBufferReader::ToValue::Args>(data)); + const Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle() || v->owner != _local_company) return; StringID msg = (v->vehstatus & VS_STOPPED) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED; @@ -2645,7 +2643,7 @@ void CcStartStopVehicle(Commands cmd, const CommandCost &result, TileIndex tile, void StartStopVehicle(const Vehicle *v, bool texteffect) { assert(v->IsPrimaryVehicle()); - Command::Post(_vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, 0, {}); + Command::Post(_vehicle_msg_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr, v->tile, v->index, false); } /** Checks whether the vehicle may be refitted at the moment.*/ @@ -2969,7 +2967,7 @@ public: break; case WID_VV_GOTO_DEPOT: // goto hangar - Command::Post(GetCmdSendToDepotMsg(v), v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0, {}); + Command::Post(GetCmdSendToDepotMsg(v), v->index, _ctrl_pressed ? DepotCommand::Service : DepotCommand::None, {}); break; case WID_VV_REFIT: // refit ShowVehicleRefitWindow(v, INVALID_VEH_ORDER_ID, this); @@ -2995,19 +2993,19 @@ public: * most likely already open, but is also visible in the vehicle viewport. */ Command::Post(_vehicle_msg_translation_table[VCT_CMD_CLONE_VEH][v->type], _ctrl_pressed ? nullptr : CcCloneVehicle, - v->tile, v->index, _ctrl_pressed ? 1 : 0, {}); + v->tile, v->index, _ctrl_pressed); break; case WID_VV_TURN_AROUND: // turn around assert(v->IsGroundVehicle()); if (v->type == VEH_ROAD) { - Command::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0, {}); + Command::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index); } else { - Command::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, 0, {}); + Command::Post(_vehicle_msg_translation_table[VCT_CMD_TURN_AROUND][v->type], v->tile, v->index, false); } break; case WID_VV_FORCE_PROCEED: // force proceed assert(v->type == VEH_TRAIN); - Command::Post(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index, 0, {}); + Command::Post(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL, v->tile, v->index); break; } } @@ -3016,7 +3014,7 @@ public: { if (str == nullptr) return; - Command::Post(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, 0, this->window_number, 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type, this->window_number, str); } void OnMouseOver(Point pt, int widget) override diff --git a/src/vehicle_type.h b/src/vehicle_type.h index ae4de36665..c302f5b9f5 100644 --- a/src/vehicle_type.h +++ b/src/vehicle_type.h @@ -61,14 +61,15 @@ enum VehiclePathFinders { VPF_YAPF = 2, ///< Yet Another PathFinder }; -/** Flags to add to p1 for goto depot commands. */ -enum DepotCommand { - DEPOT_SERVICE = (1U << 28), ///< The vehicle will leave the depot right after arrival (service only) - DEPOT_MASS_SEND = (1U << 29), ///< Tells that it's a mass send to depot command (type in VLW flag) - DEPOT_DONT_CANCEL = (1U << 30), ///< Don't cancel current goto depot command if any - DEPOT_LOCATE_HANGAR = (1U << 31), ///< Find another airport if the target one lacks a hangar - DEPOT_COMMAND_MASK = 0xFU << 28, +/** Flags for goto depot commands. */ +enum class DepotCommand : byte { + None = 0, ///< No special flags. + Service = (1U << 0), ///< The vehicle will leave the depot right after arrival (service only) + MassSend = (1U << 1), ///< Tells that it's a mass send to depot command (type in VLW flag) + DontCancel = (1U << 2), ///< Don't cancel current goto depot command if any + LocateHangar = (1U << 3), ///< Find another airport if the target one lacks a hangar }; +DECLARE_ENUM_AS_BIT_SET(DepotCommand) static const uint MAX_LENGTH_VEHICLE_NAME_CHARS = 32; ///< The maximum length of a vehicle name in characters including '\0' diff --git a/src/vehiclelist.h b/src/vehiclelist.h index 6cb2588ea6..6f6e5cb5fe 100644 --- a/src/vehiclelist.h +++ b/src/vehiclelist.h @@ -16,7 +16,7 @@ #include "tile_type.h" /** Vehicle List type flags */ -enum VehicleListType { +enum VehicleListType : byte { VL_STANDARD, VL_SHARED_ORDERS, VL_STATION_LIST, @@ -36,6 +36,8 @@ struct VehicleListIdentifier { bool UnpackIfValid(uint32 data); static VehicleListIdentifier UnPack(uint32 data); + bool Valid() const { return this->type < VLT_END; } + /** * Create a simple vehicle list. * @param type List type. From 6fe445e6c0fa3163aba48b1ec6d810b6594777bd Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 14 Nov 2021 16:39:17 +0100 Subject: [PATCH 25/60] Codechange: Un-bitstuff station/depot/waypoint commands. --- src/airport_gui.cpp | 14 +- src/cmd_helper.h | 11 ++ src/core/math_func.hpp | 2 +- src/depot_cmd.cpp | 8 +- src/depot_cmd.h | 3 +- src/depot_gui.cpp | 2 +- src/dock_gui.cpp | 15 +- src/rail_cmd.cpp | 11 +- src/rail_cmd.h | 2 +- src/rail_gui.cpp | 51 +++---- src/road_cmd.cpp | 13 +- src/road_cmd.h | 2 +- src/road_gui.cpp | 59 +++----- src/script/api/script_airport.cpp | 4 +- src/script/api/script_basestation.cpp | 4 +- src/script/api/script_marine.cpp | 8 +- src/script/api/script_rail.cpp | 29 ++-- src/script/api/script_road.cpp | 24 +--- src/script/api/script_station.cpp | 2 +- src/station_cmd.cpp | 194 ++++++++++---------------- src/station_cmd.h | 19 +-- src/station_gui.cpp | 4 +- src/station_type.h | 3 +- src/water_cmd.cpp | 9 +- src/water_cmd.h | 2 +- src/waypoint_cmd.cpp | 43 ++---- src/waypoint_cmd.h | 11 +- src/waypoint_gui.cpp | 2 +- 28 files changed, 218 insertions(+), 333 deletions(-) diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 0de11c9545..5efbb98a30 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -58,20 +58,16 @@ void CcBuildAirport(Commands cmd, const CommandCost &result, TileIndex tile, con static void PlaceAirport(TileIndex tile) { if (_selected_airport_index == -1) return; - uint32 p2 = _ctrl_pressed; - SB(p2, 16, 16, INVALID_STATION); // no station to join - uint32 p1 = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex(); - p1 |= _selected_airport_layout << 8; + byte airport_type = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex(); + byte layout = _selected_airport_layout; + bool adjacent = _ctrl_pressed; auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, p1, p2, {}).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, airport_type, layout, INVALID_STATION, adjacent).Succeeded(); } else { - uint32 p2_final = p2; - if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - - return Command::Post(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, tile, p1, p2_final, {}); + return Command::Post(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, tile, airport_type, layout, to_join, adjacent); } }; diff --git a/src/cmd_helper.h b/src/cmd_helper.h index ceb4d4bd9b..03b6e8ea77 100644 --- a/src/cmd_helper.h +++ b/src/cmd_helper.h @@ -31,4 +31,15 @@ template static inline T Extract(U v) return IsInsideMM(masked, EnumPropsT::begin, EnumPropsT::end) ? (T)masked : EnumPropsT::invalid; } +/** + * Check if an enum value is inside it's valid values. + * @tparam T Type of enum. + * @param v The value to validate + * @return True if enum is valid. + */ +template static constexpr inline bool IsEnumValid(T v) noexcept +{ + return IsInsideMM(v, EnumPropsT::begin, EnumPropsT::end); +} + #endif /* CMD_HELPER_H */ diff --git a/src/core/math_func.hpp b/src/core/math_func.hpp index 222b4120e3..8f9b5626c9 100644 --- a/src/core/math_func.hpp +++ b/src/core/math_func.hpp @@ -201,7 +201,7 @@ static inline bool IsInsideBS(const T x, const size_t base, const size_t size) * @see IsInsideBS() */ template -static inline bool IsInsideMM(const T x, const size_t min, const size_t max) +static constexpr inline bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept { return (size_t)(x - min) < (max - min); } diff --git a/src/depot_cmd.cpp b/src/depot_cmd.cpp index 1ffaeb70b2..294de69e32 100644 --- a/src/depot_cmd.cpp +++ b/src/depot_cmd.cpp @@ -39,15 +39,13 @@ static bool IsUniqueDepotName(const std::string &name) /** * Rename a depot. * @param flags type of operation - * @param tile unused - * @param p1 id of depot - * @param p2 unused + * @param depot_id id of depot * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameDepot(DoCommandFlag flags, DepotID depot_id, const std::string &text) { - Depot *d = Depot::GetIfValid(p1); + Depot *d = Depot::GetIfValid(depot_id); if (d == nullptr) return CMD_ERROR; CommandCost ret = CheckTileOwnership(d->xy); diff --git a/src/depot_cmd.h b/src/depot_cmd.h index cc9701fb7f..d476aecaf9 100644 --- a/src/depot_cmd.h +++ b/src/depot_cmd.h @@ -11,8 +11,9 @@ #define DEPOT_CMD_H #include "command_type.h" +#include "depot_type.h" -CommandProc CmdRenameDepot; +CommandCost CmdRenameDepot(DoCommandFlag flags, DepotID depot_id, const std::string &text); DEF_CMD_TRAIT(CMD_RENAME_DEPOT, CmdRenameDepot, 0, CMDT_OTHER_MANAGEMENT) diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 1b5929de7e..7fd2e03471 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -837,7 +837,7 @@ struct DepotWindow : Window { if (str == nullptr) return; /* Do depot renaming */ - Command::Post(STR_ERROR_CAN_T_RENAME_DEPOT, 0, this->GetDepotIndex(), 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_DEPOT, this->GetDepotIndex(), str); } bool OnRightClick(Point pt, int widget) override diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 328ce1c20c..cdcb4ea84a 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -204,7 +204,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_DEPOT: // Build depot button - Command::Post(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT, CcBuildDocks, tile, _ship_depot_direction, 0, {}); + Command::Post(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT, CcBuildDocks, tile, _ship_depot_direction); break; case WID_DT_STATION: { // Build station button @@ -212,17 +212,12 @@ struct BuildDocksToolbarWindow : Window { DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile); - uint32 p1 = _ctrl_pressed; - uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join - + bool adjacent = _ctrl_pressed; auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, p1, p2, {}).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, INVALID_STATION, adjacent).Succeeded(); } else { - uint32 p2_final = p2; - if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - - return Command::Post(STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, tile, p1, p2_final, {}); + return Command::Post(STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, tile, to_join, adjacent); } }; @@ -231,7 +226,7 @@ struct BuildDocksToolbarWindow : Window { } case WID_DT_BUOY: // Build buoy button - Command::Post(STR_ERROR_CAN_T_POSITION_BUOY_HERE, CcBuildDocks, tile, 0, 0, {}); + Command::Post(STR_ERROR_CAN_T_POSITION_BUOY_HERE, CcBuildDocks, tile); break; case WID_DT_RIVER: // Build river button (in scenario editor) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 066fb78200..389c44dd98 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -976,24 +976,21 @@ CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex tile, uint32 p * Build a train depot * @param flags operation to perform * @param tile position of the train depot - * @param p1 rail type - * @param p2 bit 0..1 entrance direction (DiagDirection) + * @param railtype rail type + * @param dir entrance direction * @param text unused * @return the cost of this operation or an error * * @todo When checking for the tile slope, * distinguish between "Flat land required" and "land sloped in wrong direction" */ -CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir) { /* check railtype and valid direction for depot (0 through 3), 4 in total */ - RailType railtype = Extract(p1); - if (!ValParamRailtype(railtype)) return CMD_ERROR; + if (!ValParamRailtype(railtype) || !IsEnumValid(dir)) return CMD_ERROR; Slope tileh = GetTileSlope(tile); - DiagDirection dir = Extract(p2); - CommandCost cost(EXPENSES_CONSTRUCTION); /* Prohibit construction if diff --git a/src/rail_cmd.h b/src/rail_cmd.h index 1fb0fdee0d..31266e2b03 100644 --- a/src/rail_cmd.h +++ b/src/rail_cmd.h @@ -16,7 +16,7 @@ CommandProc CmdBuildRailroadTrack; CommandProc CmdRemoveRailroadTrack; CommandProc CmdBuildSingleRail; CommandProc CmdRemoveSingleRail; -CommandProc CmdBuildTrainDepot; +CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir); CommandProc CmdBuildSingleSignal; CommandProc CmdRemoveSingleSignal; CommandProc CmdConvertRail; diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index c1c45d5d72..60ac12c726 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -139,8 +139,7 @@ void CcRailDepot(Commands cmd, const CommandCost &result, TileIndex tile, const { if (result.Failed()) return; - auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); - DiagDirection dir = (DiagDirection)p2; + auto [tile_, rt, dir] = EndianBufferReader::ToValue::Args>(data); if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); @@ -173,7 +172,7 @@ static void PlaceRail_Waypoint(TileIndex tile) } else { /* Tile where we can't build rail waypoints. This is always going to fail, * but provides the user with a proper error message. */ - Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, tile, 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, {}); + Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, tile, AXIS_X, 1, 1, STAT_CLASS_WAYP, 0, INVALID_STATION, false); } } @@ -199,21 +198,21 @@ static void PlaceRail_Station(TileIndex tile) VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION); VpSetPlaceSizingLimit(_settings_game.station.station_spread); } else { - uint32 p1 = _cur_railtype | _railstation.orientation << 6 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24; - uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16; - int w = _settings_client.gui.station_numtracks; int h = _settings_client.gui.station_platlength; if (!_railstation.orientation) Swap(w, h); + RailStationGUISettings params = _railstation; + RailType rt = _cur_railtype; + byte numtracks = _settings_client.gui.station_numtracks; + byte platlength = _settings_client.gui.station_platlength; + bool adjacent = _ctrl_pressed; + auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, p1, p2, {}).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, rt, params.orientation, numtracks, platlength, params.station_class, params.station_type, INVALID_STATION, adjacent).Succeeded(); } else { - uint32 p2_final = p2; - if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - - return Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, tile, p1, p2_final, {}); + return Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, tile, rt, params.orientation, numtracks, platlength, params.station_class, params.station_type, to_join, adjacent); } }; @@ -664,7 +663,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_DEPOT: - Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, CcRailDepot, tile, _cur_railtype, _build_depot_direction, {}); + Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT, CcRailDepot, tile, _cur_railtype, _build_depot_direction); break; case WID_RAT_BUILD_WAYPOINT: @@ -734,27 +733,25 @@ struct BuildRailToolbarWindow : Window { if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) { /* Station */ if (_remove_button_clicked) { - Command::Post(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1, {}); + Command::Post(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed); } else { HandleStationPlacement(start_tile, end_tile); } } else { /* Waypoint */ if (_remove_button_clicked) { - Command::Post(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed ? 0 : 1, {}); + Command::Post(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _ctrl_pressed); } else { TileArea ta(start_tile, end_tile); - uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 6 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24; - uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16; + Axis axis = select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y; + bool adjacent = _ctrl_pressed; + byte waypoint_type = _cur_waypoint_type; auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, p1, p2, {}).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, axis, ta.w, ta.h, STAT_CLASS_WAYP, waypoint_type, INVALID_STATION, adjacent).Succeeded(); } else { - uint32 p2_final = p2; - if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - - return Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, ta.tile, p1, p2_final, {}); + return Command::Post(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, ta.tile, axis, ta.w, ta.h, STAT_CLASS_WAYP, waypoint_type, to_join, adjacent); } }; @@ -913,17 +910,15 @@ static void HandleStationPlacement(TileIndex start, TileIndex end) if (_railstation.orientation == AXIS_X) Swap(numtracks, platlength); - uint32 p1 = _cur_railtype | _railstation.orientation << 6 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24; - uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16; + RailStationGUISettings params = _railstation; + RailType rt = _cur_railtype; + bool adjacent = _ctrl_pressed; auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, p1, p2, {}).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, rt, params.orientation, numtracks, platlength, params.station_class, params.station_type, INVALID_STATION, adjacent).Succeeded(); } else { - uint32 p2_final = p2; - if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - - return Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, ta.tile, p1, p2_final, {}); + return Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, ta.tile, rt, params.orientation, numtracks, platlength, params.station_class, params.station_type, to_join, adjacent); } }; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 637b476d0d..72dcb5276e 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1157,21 +1157,16 @@ CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 * Build a road depot. * @param tile tile where to build the depot * @param flags operation to perform - * @param p1 bit 0..1 entrance direction (DiagDirection) - * bit 2..7 road type - * @param p2 unused - * @param text unused + * @param rt road type + * @param dir entrance direction * @return the cost of this operation or an error * * @todo When checking for the tile slope, * distinguish between "Flat land required" and "land sloped in wrong direction" */ -CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, RoadType rt, DiagDirection dir) { - DiagDirection dir = Extract(p1); - - RoadType rt = Extract(p1); - if (!ValParamRoadType(rt)) return CMD_ERROR; + if (!ValParamRoadType(rt) || !IsEnumValid(dir)) return CMD_ERROR; CommandCost cost(EXPENSES_CONSTRUCTION); diff --git a/src/road_cmd.h b/src/road_cmd.h index 05f064b0bc..0cab1252f0 100644 --- a/src/road_cmd.h +++ b/src/road_cmd.h @@ -20,7 +20,7 @@ void UpdateNearestTownForRoadTiles(bool invalidate); CommandProc CmdBuildLongRoad; CommandProc CmdRemoveLongRoad; CommandProc CmdBuildRoad; -CommandProc CmdBuildRoadDepot; +CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, RoadType rt, DiagDirection dir); CommandProc CmdConvertRoad; DEF_CMD_TRAIT(CMD_BUILD_LONG_ROAD, CmdBuildLongRoad, CMD_AUTO | CMD_NO_WATER | CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/road_gui.cpp b/src/road_gui.cpp index a777c9c1d1..beba949e4c 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -133,9 +133,8 @@ void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, const { if (result.Failed()) return; - auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); + auto [tile_, rt, dir] = EndianBufferReader::ToValue::Args>(data); - DiagDirection dir = (DiagDirection)GB(p1, 0, 2); if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); ConnectRoadToStructure(tile, dir); @@ -146,32 +145,22 @@ void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, const * @param result Result of the build road stop command. * @param cmd Unused. * @param tile Start tile. - * @param p1 bit 0..7: Width of the road stop. - * bit 8..15: Length of the road stop. - * @param p2 bit 0: 0 For bus stops, 1 for truck stops. - * bit 1: 0 For normal stops, 1 for drive-through. - * bit 2: Allow stations directly adjacent to other stations. - * bit 3..4: Entrance direction (#DiagDirection) for normal stops. - * bit 3: #Axis of the road for drive-through stops. - * bit 5..9: The roadtype. - * bit 16..31: Station ID to join (NEW_STATION if build new one). - * @param text Unused. + * @param data Command data. * @see CmdBuildRoadStop */ void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) { if (result.Failed()) return; - auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); + auto [tile_, width, length, stop_type, is_drive_through, dir, rt, station_to_join, adjacent] = EndianBufferReader::ToValue::Args>(data); - DiagDirection dir = (DiagDirection)GB(p2, 3, 2); if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - TileArea roadstop_area(tile, GB(p1, 0, 8), GB(p1, 8, 8)); + TileArea roadstop_area(tile, width, length); for (TileIndex cur_tile : roadstop_area) { ConnectRoadToStructure(cur_tile, dir); /* For a drive-through road stop build connecting road for other entrance. */ - if (HasBit(p2, 1)) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir)); + if (is_drive_through) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir)); } } @@ -179,34 +168,24 @@ void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, const C * Place a new road stop. * @param start_tile First tile of the area. * @param end_tile Last tile of the area. - * @param p2 bit 0: 0 For bus stops, 1 for truck stops. - * bit 2: Allow stations directly adjacent to other stations. - * bit 5..10: The roadtypes. + * @param stop_type Type of stop (bus/truck). + * @param adjacent Allow stations directly adjacent to other stations. + * @param rt The roadtypes. * @param err_msg Error message to show. * @see CcRoadStop() */ -static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, StringID err_msg) +static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_type, bool adjacent, RoadType rt, StringID err_msg) { TileArea ta(start_tile, end_tile); - uint32 p1 = (uint32)(ta.w | ta.h << 8); - - uint8 ddir = _road_station_picker_orientation; - SB(p2, 16, 16, INVALID_STATION); // no station to join - - if (ddir >= DIAGDIR_END) { - SetBit(p2, 1); // It's a drive-through stop. - ddir -= DIAGDIR_END; // Adjust picker result to actual direction. - } - p2 |= ddir << 3; // Set the DiagDirecion into p2 bits 3 and 4. + DiagDirection ddir = _road_station_picker_orientation; + bool drive_through = ddir >= DIAGDIR_END; + if (drive_through) ddir = static_cast(ddir - DIAGDIR_END); // Adjust picker result to actual direction. auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, p1, p2, {}).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, ta.w, ta.h, stop_type, drive_through, ddir, rt, INVALID_STATION, adjacent).Succeeded(); } else { - uint32 p2_final = p2; - if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join); - - return Command::Post(err_msg, CcRoadStop, ta.tile, p1, p2_final, {}); + return Command::Post(err_msg, CcRoadStop, ta.tile, ta.w, ta.h, stop_type, drive_through, ddir, rt, to_join, adjacent); } }; @@ -568,7 +547,7 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_DEPOT: Command::Post(this->rti->strings.err_depot, CcRoadDepot, - tile, _cur_roadtype << 2 | _road_depot_orientation, 0, {}); + tile, _cur_roadtype, _road_depot_orientation); break; case WID_ROT_BUS_STATION: @@ -700,9 +679,9 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_BUS_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - Command::Post(this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS, {}); + Command::Post(this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, ROADSTOP_BUS, _ctrl_pressed); } else { - PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, this->rti->strings.err_build_station[ROADSTOP_BUS]); + PlaceRoadStop(start_tile, end_tile, ROADSTOP_BUS, _ctrl_pressed, _cur_roadtype, this->rti->strings.err_build_station[ROADSTOP_BUS]); } } break; @@ -712,9 +691,9 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - Command::Post(this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, {}); + Command::Post(this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, ROADSTOP_TRUCK, _ctrl_pressed); } else { - PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, this->rti->strings.err_build_station[ROADSTOP_TRUCK]); + PlaceRoadStop(start_tile, end_tile, ROADSTOP_TRUCK, _ctrl_pressed, _cur_roadtype, this->rti->strings.err_build_station[ROADSTOP_TRUCK]); } } break; diff --git a/src/script/api/script_airport.cpp b/src/script/api/script_airport.cpp index 5927b16620..8ed4dbfcac 100644 --- a/src/script/api/script_airport.cpp +++ b/src/script/api/script_airport.cpp @@ -77,9 +77,7 @@ EnforcePrecondition(false, IsValidAirportType(type)); EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id)); - uint p2 = station_id == ScriptStation::STATION_JOIN_ADJACENT ? 0 : 1; - p2 |= (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; - return ScriptObject::Command::Do(tile, type, p2, {}); + return ScriptObject::Command::Do(tile, type, 0, (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION), station_id == ScriptStation::STATION_JOIN_ADJACENT); } /* static */ bool ScriptAirport::RemoveAirport(TileIndex tile) diff --git a/src/script/api/script_basestation.cpp b/src/script/api/script_basestation.cpp index a249344101..788d549500 100644 --- a/src/script/api/script_basestation.cpp +++ b/src/script/api/script_basestation.cpp @@ -45,9 +45,9 @@ EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_STATION_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); if (::Station::IsValidID(station_id)) { - return ScriptObject::Command::Do(0, station_id, 0, text); + return ScriptObject::Command::Do(station_id, text); } else { - return ScriptObject::Command::Do(0, station_id, 0, text); + return ScriptObject::Command::Do(station_id, text); } } diff --git a/src/script/api/script_marine.cpp b/src/script/api/script_marine.cpp index f368ec9185..8093233948 100644 --- a/src/script/api/script_marine.cpp +++ b/src/script/api/script_marine.cpp @@ -83,7 +83,7 @@ EnforcePrecondition(false, ::IsValidTile(front)); EnforcePrecondition(false, (::TileX(front) == ::TileX(tile)) != (::TileY(front) == ::TileY(tile))); - return ScriptObject::Command::Do(tile, ::TileX(front) == ::TileX(tile), 0, {}); + return ScriptObject::Command::Do(tile, ::TileX(front) == ::TileX(tile) ? AXIS_Y : AXIS_X); } /* static */ bool ScriptMarine::BuildDock(TileIndex tile, StationID station_id) @@ -92,9 +92,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id)); - uint p1 = station_id == ScriptStation::STATION_JOIN_ADJACENT ? 0 : 1; - uint p2 = (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; - return ScriptObject::Command::Do(tile, p1, p2, {}); + return ScriptObject::Command::Do(tile, ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION, station_id != ScriptStation::STATION_JOIN_ADJACENT); } /* static */ bool ScriptMarine::BuildBuoy(TileIndex tile) @@ -102,7 +100,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ bool ScriptMarine::BuildLock(TileIndex tile) diff --git a/src/script/api/script_rail.cpp b/src/script/api/script_rail.cpp index ebba16343c..30a1085d48 100644 --- a/src/script/api/script_rail.cpp +++ b/src/script/api/script_rail.cpp @@ -142,9 +142,9 @@ EnforcePrecondition(false, ::TileX(tile) == ::TileX(front) || ::TileY(tile) == ::TileY(front)); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); - uint entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0); + DiagDirection entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? DIAGDIR_SE : DIAGDIR_NW) : (::TileX(tile) < ::TileX(front) ? DIAGDIR_SW : DIAGDIR_NE); - return ScriptObject::Command::Do(tile, ScriptObject::GetRailType(), entrance_dir, {}); + return ScriptObject::Command::Do(tile, (::RailType)ScriptObject::GetRailType(), entrance_dir); } /* static */ bool ScriptRail::BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id) @@ -157,10 +157,8 @@ EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id)); - uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8); - if (direction == RAILTRACK_NW_SE) p1 |= (1 << 6); - if (station_id != ScriptStation::STATION_JOIN_ADJACENT) p1 |= (1 << 24); - return ScriptObject::Command::Do(tile, p1, (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16, {}); + bool adjacent = station_id != ScriptStation::STATION_JOIN_ADJACENT; + return ScriptObject::Command::Do(tile, (::RailType)GetCurrentRailType(), direction == RAILTRACK_NW_SE ? AXIS_Y : AXIS_X, num_platforms, platform_length, STAT_CLASS_DFLT, 0, ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION, adjacent); } /* static */ bool ScriptRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station) @@ -176,10 +174,6 @@ EnforcePrecondition(false, source_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || source_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(source_industry)); EnforcePrecondition(false, goal_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || goal_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(goal_industry)); - uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8); - if (direction == RAILTRACK_NW_SE) p1 |= 1 << 6; - if (station_id != ScriptStation::STATION_JOIN_ADJACENT) p1 |= (1 << 24); - const GRFFile *file; uint16 res = GetAiPurchaseCallbackResult( GSF_STATIONS, @@ -193,7 +187,10 @@ std::min(15u, num_platforms) << 4 | std::min(15u, platform_length), &file ); - uint32 p2 = (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; + + Axis axis = direction == RAILTRACK_NW_SE ? AXIS_Y : AXIS_X; + bool adjacent = station_id != ScriptStation::STATION_JOIN_ADJACENT; + StationID to_join = ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION; if (res != CALLBACK_FAILED) { int index = 0; const StationSpec *spec = StationClass::GetByGrf(file->grfid, res, &index); @@ -201,11 +198,11 @@ Debug(grf, 1, "{} returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename); } else { /* We might have gotten an usable station spec. Try to build it, but if it fails we'll fall back to the original station. */ - if (ScriptObject::Command::Do(tile, p1, p2 | spec->cls_id | index << 8, {})) return true; + if (ScriptObject::Command::Do(tile, (::RailType)GetCurrentRailType(), axis, num_platforms, platform_length, spec->cls_id, index, to_join, adjacent)) return true; } } - return ScriptObject::Command::Do(tile, p1, p2, {}); + return ScriptObject::Command::Do(tile, (::RailType)GetCurrentRailType(), axis, num_platforms, platform_length, STAT_CLASS_DFLT, 0, to_join, adjacent); } /* static */ bool ScriptRail::BuildRailWaypoint(TileIndex tile) @@ -216,7 +213,7 @@ EnforcePrecondition(false, GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); - return ScriptObject::Command::Do(tile, GetCurrentRailType() | (GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y) << 6 | 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, {}); + return ScriptObject::Command::Do(tile, GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y, 1, 1, STAT_CLASS_WAYP, 0, INVALID_STATION, false); } /* static */ bool ScriptRail::RemoveRailWaypointTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail) @@ -225,7 +222,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(tile2)); - return ScriptObject::Command::Do(tile, tile2, keep_rail ? 1 : 0, {}); + return ScriptObject::Command::Do(tile, tile2, keep_rail); } /* static */ bool ScriptRail::RemoveRailStationTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail) @@ -234,7 +231,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(tile2)); - return ScriptObject::Command::Do(tile, tile2, keep_rail ? 1 : 0, {}); + return ScriptObject::Command::Do(tile, tile2, keep_rail); } /* static */ uint ScriptRail::GetRailTracks(TileIndex tile) diff --git a/src/script/api/script_road.cpp b/src/script/api/script_road.cpp index 26cdb5190a..c629396b70 100644 --- a/src/script/api/script_road.cpp +++ b/src/script/api/script_road.cpp @@ -529,9 +529,9 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, ::TileX(tile) == ::TileX(front) || ::TileY(tile) == ::TileY(front)); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - uint entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0); + DiagDirection entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? DIAGDIR_SE : DIAGDIR_NW) : (::TileX(tile) < ::TileX(front) ? DIAGDIR_SW : DIAGDIR_NE); - return ScriptObject::Command::Do(tile, entrance_dir | (ScriptObject::GetRoadType() << 2), 0, {}); + return ScriptObject::Command::Do(tile, ScriptObject::GetRoadType(), entrance_dir); } /* static */ bool ScriptRoad::_BuildRoadStationInternal(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, bool drive_through, StationID station_id) @@ -545,20 +545,10 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, road_veh_type == ROADVEHTYPE_BUS || road_veh_type == ROADVEHTYPE_TRUCK); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - uint entrance_dir; - if (drive_through) { - entrance_dir = ::TileY(tile) != ::TileY(front); - } else { - entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0); - } - - uint p2 = station_id == ScriptStation::STATION_JOIN_ADJACENT ? 0 : 4; - p2 |= drive_through ? 2 : 0; - p2 |= road_veh_type == ROADVEHTYPE_TRUCK ? 1 : 0; - p2 |= ScriptObject::GetRoadType() << 5; - p2 |= entrance_dir << 3; - p2 |= (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; - return ScriptObject::Command::Do(tile, 1 | 1 << 8, p2, {}); + DiagDirection entrance_dir = DiagdirBetweenTiles(tile, front); + RoadStopType stop_type = road_veh_type == ROADVEHTYPE_TRUCK ? ROADSTOP_TRUCK : ROADSTOP_BUS; + StationID to_join = ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION; + return ScriptObject::Command::Do(tile, 1, 1, stop_type, drive_through, entrance_dir, ScriptObject::GetRoadType(), to_join, station_id != ScriptStation::STATION_JOIN_ADJACENT); } /* static */ bool ScriptRoad::BuildRoadStation(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, StationID station_id) @@ -612,7 +602,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, IsTileType(tile, MP_STATION)); EnforcePrecondition(false, IsRoadStop(tile)); - return ScriptObject::Command::Do(tile, 1 | 1 << 8, GetRoadStopType(tile), {}); + return ScriptObject::Command::Do(tile, 1, 1, GetRoadStopType(tile), false); } /* static */ Money ScriptRoad::GetBuildCost(RoadType roadtype, BuildType build_type) diff --git a/src/script/api/script_station.cpp b/src/script/api/script_station.cpp index 34e7d84341..3b38844df6 100644 --- a/src/script/api/script_station.cpp +++ b/src/script/api/script_station.cpp @@ -240,5 +240,5 @@ template EnforcePrecondition(false, IsValidStation(station_id)); EnforcePrecondition(false, HasStationType(station_id, STATION_AIRPORT)); - return ScriptObject::Command::Do(0, station_id, 0, {}); + return ScriptObject::Command::Do(station_id); } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 33f86146c4..bdc58588b9 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1241,37 +1241,23 @@ static void RestoreTrainReservation(Train *v) * Build rail station * @param flags operation to perform * @param tile_org northern most position of station dragging/placement - * @param p1 various bitstuffed elements - * - p1 = (bit 0- 5) - railtype - * - p1 = (bit 6) - orientation (Axis) - * - p1 = (bit 8-15) - number of tracks - * - p1 = (bit 16-23) - platform length - * - p1 = (bit 24) - allow stations directly adjacent to other stations. - * @param p2 various bitstuffed elements - * - p2 = (bit 0- 7) - custom station class - * - p2 = (bit 8-15) - custom station id - * - p2 = (bit 16-31) - station ID to join (NEW_STATION if build new one) - * @param text unused + * @param rt railtype + * @param axis orientation (Axis) + * @param numtracks number of tracks + * @param plat_len platform length + * @param spec_class custom station class + * @param spec_index custom station id + * @param station_to_join station ID to join (NEW_STATION if build new one) + * @param adjacent allow stations directly adjacent to other stations. * @return the cost of this operation or an error */ -CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailType rt, Axis axis, byte numtracks, byte plat_len, StationClassID spec_class, byte spec_index, StationID station_to_join, bool adjacent) { - /* Unpack parameters */ - RailType rt = Extract(p1); - Axis axis = Extract(p1); - byte numtracks = GB(p1, 8, 8); - byte plat_len = GB(p1, 16, 8); - bool adjacent = HasBit(p1, 24); - - StationClassID spec_class = Extract(p2); - byte spec_index = GB(p2, 8, 8); - StationID station_to_join = GB(p2, 16, 16); - /* Does the authority allow this? */ CommandCost ret = CheckIfAuthorityAllowsNewStation(tile_org, flags); if (ret.Failed()) return ret; - if (!ValParamRailtype(rt)) return CMD_ERROR; + if (!ValParamRailtype(rt) || !IsEnumValid(axis)) return CMD_ERROR; /* Check if the given station class is valid */ if ((uint)spec_class >= StationClass::GetClassCount() || spec_class == STAT_CLASS_WAYP) return CMD_ERROR; @@ -1657,21 +1643,19 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_st * This allows for custom-built station with holes and weird layouts * @param flags operation to perform * @param start tile of station piece to remove - * @param p1 start_tile - * @param p2 various bitstuffed elements - * - p2 = bit 0 - if set keep the rail - * @param text unused + * @param end other edge of the rect to remove + * @param keep_rail if set keep the rail * @return the cost of this operation or an error */ -CommandCost CmdRemoveFromRailStation(DoCommandFlag flags, TileIndex start, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveFromRailStation(DoCommandFlag flags, TileIndex start, TileIndex end, bool keep_rail) { - TileIndex end = p1 == 0 ? start : p1; + if (end == 0) end = start; if (start >= MapSize() || end >= MapSize()) return CMD_ERROR; TileArea ta(start, end); std::vector affected_stations; - CommandCost ret = RemoveFromRailBaseStation(ta, affected_stations, flags, _price[PR_CLEAR_STATION_RAIL], HasBit(p2, 0)); + CommandCost ret = RemoveFromRailBaseStation(ta, affected_stations, flags, _price[PR_CLEAR_STATION_RAIL], keep_rail); if (ret.Failed()) return ret; /* Do all station specific functions here. */ @@ -1691,21 +1675,19 @@ CommandCost CmdRemoveFromRailStation(DoCommandFlag flags, TileIndex start, uint3 * This allows for custom-built waypoint with holes and weird layouts * @param flags operation to perform * @param start tile of waypoint piece to remove - * @param p1 start_tile - * @param p2 various bitstuffed elements - * - p2 = bit 0 - if set keep the rail - * @param text unused + * @param end other edge of the rect to remove + * @param keep_rail if set keep the rail * @return the cost of this operation or an error */ -CommandCost CmdRemoveFromRailWaypoint(DoCommandFlag flags, TileIndex start, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveFromRailWaypoint(DoCommandFlag flags, TileIndex start, TileIndex end, bool keep_rail) { - TileIndex end = p1 == 0 ? start : p1; + if (end == 0) end = start; if (start >= MapSize() || end >= MapSize()) return CMD_ERROR; TileArea ta(start, end); std::vector affected_stations; - return RemoveFromRailBaseStation(ta, affected_stations, flags, _price[PR_CLEAR_WAYPOINT_RAIL], HasBit(p2, 0)); + return RemoveFromRailBaseStation(ta, affected_stations, flags, _price[PR_CLEAR_WAYPOINT_RAIL], keep_rail); } @@ -1756,7 +1738,7 @@ static CommandCost RemoveRailStation(TileIndex tile, DoCommandFlag flags) { /* if there is flooding, remove platforms tile by tile */ if (_current_company == OWNER_WATER) { - return Command::Do(DC_EXEC, tile, 0, 0, {}); + return Command::Do(DC_EXEC, tile, 0, false); } Station *st = Station::GetByTile(tile); @@ -1777,7 +1759,7 @@ static CommandCost RemoveRailWaypoint(TileIndex tile, DoCommandFlag flags) { /* if there is flooding, remove waypoints tile by tile */ if (_current_company == OWNER_WATER) { - return Command::Do(DC_EXEC, tile, 0, 0, {}); + return Command::Do(DC_EXEC, tile, 0, false); } return RemoveRailStation(Waypoint::GetByTile(tile), flags, _price[PR_CLEAR_WAYPOINT_RAIL]); @@ -1824,32 +1806,23 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio * Build a bus or truck stop. * @param flags Operation to perform. * @param tile Northernmost tile of the stop. - * @param p1 bit 0..7: Width of the road stop. - * bit 8..15: Length of the road stop. - * @param p2 bit 0: 0 For bus stops, 1 for truck stops. - * bit 1: 0 For normal stops, 1 for drive-through. - * bit 2: Allow stations directly adjacent to other stations. - * bit 3..4: Entrance direction (#DiagDirection) for normal stops. - * bit 3: #Axis of the road for drive-through stops. - * bit 5..10: The roadtype. - * bit 16..31: Station ID to join (NEW_STATION if build new one). - * @param text Unused. + * @param width Width of the road stop. + * @param length Length of the road stop. + * @param stop_type Type of road stop (bus/truck). + * @param is_drive_through False for normal stops, true for drive-through. + * @param ddir Entrance direction (#DiagDirection) for normal stops. Converted to the axis for drive-through stops. + * @param rt The roadtype. + * @param station_to_join Station ID to join (NEW_STATION if build new one). + * @param adjacent Allow stations directly adjacent to other stations. * @return The cost of this operation or an error. */ -CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint8 length, RoadStopType stop_type, bool is_drive_through, DiagDirection ddir, RoadType rt, StationID station_to_join, bool adjacent) { - bool type = HasBit(p2, 0); - bool is_drive_through = HasBit(p2, 1); - RoadType rt = Extract(p2); - if (!ValParamRoadType(rt)) return CMD_ERROR; - StationID station_to_join = GB(p2, 16, 16); + if (!ValParamRoadType(rt) || !IsEnumValid(ddir) || stop_type >= ROADSTOP_END) return CMD_ERROR; bool reuse = (station_to_join != NEW_STATION); if (!reuse) station_to_join = INVALID_STATION; bool distant_join = (station_to_join != INVALID_STATION); - uint8 width = (uint8)GB(p1, 0, 8); - uint8 length = (uint8)GB(p1, 8, 8); - /* Check if the requested road stop is too big */ if (width > _settings_game.station.station_spread || length > _settings_game.station.station_spread) return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT); /* Check for incorrect width / length. */ @@ -1864,34 +1837,26 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint32 p1, uin /* Trams only have drive through stops */ if (!is_drive_through && RoadTypeIsTram(rt)) return CMD_ERROR; - DiagDirection ddir; - Axis axis; - if (is_drive_through) { - /* By definition axis is valid, due to there being 2 axes and reading 1 bit. */ - axis = Extract(p2); - ddir = AxisToDiagDir(axis); - } else { - /* By definition ddir is valid, due to there being 4 diagonal directions and reading 2 bits. */ - ddir = Extract(p2); - axis = DiagDirToAxis(ddir); - } + Axis axis = DiagDirToAxis(ddir); CommandCost ret = CheckIfAuthorityAllowsNewStation(tile, flags); if (ret.Failed()) return ret; + bool is_truck_stop = stop_type != ROADSTOP_BUS; + /* Total road stop cost. */ - CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[type ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]); + CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]); StationID est = INVALID_STATION; - ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, type, axis, &est, rt); + ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, is_truck_stop, axis, &est, rt); if (ret.Failed()) return ret; cost.AddCost(ret); Station *st = nullptr; - ret = FindJoiningRoadStop(est, station_to_join, HasBit(p2, 2), roadstop_area, &st); + ret = FindJoiningRoadStop(est, station_to_join, adjacent, roadstop_area, &st); if (ret.Failed()) return ret; /* Check if this number of road stops can be allocated. */ - if (!RoadStop::CanAllocateItem(roadstop_area.w * roadstop_area.h)) return_cmd_error(type ? STR_ERROR_TOO_MANY_TRUCK_STOPS : STR_ERROR_TOO_MANY_BUS_STOPS); + if (!RoadStop::CanAllocateItem(roadstop_area.w * roadstop_area.h)) return_cmd_error(is_truck_stop ? STR_ERROR_TOO_MANY_TRUCK_STOPS : STR_ERROR_TOO_MANY_BUS_STOPS); ret = BuildStationPart(&st, flags, reuse, roadstop_area, STATIONNAMING_ROAD); if (ret.Failed()) return ret; @@ -1911,21 +1876,21 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint32 p1, uin RoadStop *road_stop = new RoadStop(cur_tile); /* Insert into linked list of RoadStops. */ - RoadStop **currstop = FindRoadStopSpot(type, st); + RoadStop **currstop = FindRoadStopSpot(is_truck_stop, st); *currstop = road_stop; - if (type) { + if (is_truck_stop) { st->truck_station.Add(cur_tile); } else { st->bus_station.Add(cur_tile); } /* Initialize an empty station. */ - st->AddFacility((type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, cur_tile); + st->AddFacility(is_truck_stop ? FACIL_TRUCK_STOP : FACIL_BUS_STOP, cur_tile); st->rect.BeforeAddTile(cur_tile, StationRect::ADD_TRY); - RoadStopType rs_type = type ? ROADSTOP_TRUCK : ROADSTOP_BUS; + RoadStopType rs_type = is_truck_stop ? ROADSTOP_TRUCK : ROADSTOP_BUS; if (is_drive_through) { /* Update company infrastructure counts. If the current tile is a normal road tile, remove the old * bits first. */ @@ -1956,7 +1921,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint32 p1, uin } if (st != nullptr) { - st->AfterStationTileSetChange(true, type ? STATION_TRUCK: STATION_BUS); + st->AfterStationTileSetChange(true, is_truck_stop ? STATION_TRUCK: STATION_BUS); } return cost; } @@ -2079,25 +2044,21 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) * Remove bus or truck stops. * @param flags Operation to perform. * @param tile Northernmost tile of the removal area. - * @param p1 bit 0..7: Width of the removal area. - * bit 8..15: Height of the removal area. - * @param p2 bit 0: 0 For bus stops, 1 for truck stops. - * @param p2 bit 1: 0 to keep roads of all drive-through stops, 1 to remove them. - * @param text Unused. + * @param width Width of the removal area. + * @param height Height of the removal area. + * @param stop_type Type of stop (bus/truck). + * @param remove_road Remove roads of drive-through stops? * @return The cost of this operation or an error. */ -CommandCost CmdRemoveRoadStop(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint height, RoadStopType stop_type, bool remove_road) { - uint8 width = (uint8)GB(p1, 0, 8); - uint8 height = (uint8)GB(p1, 8, 8); - bool keep_drive_through_roads = !HasBit(p2, 1); - + if (stop_type >= ROADSTOP_END) return CMD_ERROR; /* Check for incorrect width / height. */ if (width == 0 || height == 0) return CMD_ERROR; /* Check if the first tile and the last tile are valid */ if (!IsValidTile(tile) || TileAddWrap(tile, width - 1, height - 1) == INVALID_TILE) return CMD_ERROR; /* Bankrupting company is not supposed to remove roads, there may be road vehicles. */ - if (!keep_drive_through_roads && (flags & DC_BANKRUPT)) return CMD_ERROR; + if (remove_road && (flags & DC_BANKRUPT)) return CMD_ERROR; TileArea roadstop_area(tile, width, height); @@ -2107,7 +2068,7 @@ CommandCost CmdRemoveRoadStop(DoCommandFlag flags, TileIndex tile, uint32 p1, ui for (TileIndex cur_tile : roadstop_area) { /* Make sure the specified tile is a road stop of the correct type */ - if (!IsTileType(cur_tile, MP_STATION) || !IsRoadStop(cur_tile) || (uint32)GetRoadStopType(cur_tile) != GB(p2, 0, 1)) continue; + if (!IsTileType(cur_tile, MP_STATION) || !IsRoadStop(cur_tile) || GetRoadStopType(cur_tile) != stop_type) continue; /* Save information on to-be-restored roads before the stop is removed. */ RoadBits road_bits = ROAD_NONE; @@ -2119,7 +2080,7 @@ CommandCost CmdRemoveRoadStop(DoCommandFlag flags, TileIndex tile, uint32 p1, ui if (road_type[rtt] == INVALID_ROADTYPE) continue; road_owner[rtt] = GetRoadOwner(cur_tile, rtt); /* If we don't want to preserve our roads then restore only roads of others. */ - if (!keep_drive_through_roads && road_owner[rtt] == _current_company) road_type[rtt] = INVALID_ROADTYPE; + if (remove_road && road_owner[rtt] == _current_company) road_type[rtt] = INVALID_ROADTYPE; } road_bits = AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(cur_tile))); } @@ -2236,23 +2197,17 @@ void UpdateAirportsNoise() * Place an Airport. * @param flags operation to perform * @param tile tile where airport will be built - * @param p1 - * - p1 = (bit 0- 7) - airport type, @see airport.h - * - p1 = (bit 8-15) - airport layout - * @param p2 various bitstuffed elements - * - p2 = (bit 0) - allow airports directly adjacent to other airports. - * - p2 = (bit 16-31) - station ID to join (NEW_STATION if build new one) - * @param text unused + * @param airport_type airport type, @see airport.h + * @param layout airport layout + * @param station_to_join station ID to join (NEW_STATION if build new one) + * @param allow_adjacent allow airports directly adjacent to other airports. * @return the cost of this operation or an error */ -CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_type, byte layout, StationID station_to_join, bool allow_adjacent) { - StationID station_to_join = GB(p2, 16, 16); bool reuse = (station_to_join != NEW_STATION); if (!reuse) station_to_join = INVALID_STATION; bool distant_join = (station_to_join != INVALID_STATION); - byte airport_type = GB(p1, 0, 8); - byte layout = GB(p1, 8, 8); if (distant_join && (!_settings_game.station.distant_join_stations || !Station::IsValidID(station_to_join))) return CMD_ERROR; @@ -2313,7 +2268,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, uint32 p1, uint } Station *st = nullptr; - ret = FindJoiningStation(INVALID_STATION, station_to_join, HasBit(p2, 0), airport_area, &st); + ret = FindJoiningStation(INVALID_STATION, station_to_join, allow_adjacent, airport_area, &st); if (ret.Failed()) return ret; /* Distant join */ @@ -2456,16 +2411,13 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags) /** * Open/close an airport to incoming aircraft. * @param flags Operation to perform. - * @param tile Unused. - * @param p1 Station ID of the airport. - * @param p2 Unused. - * @param text unused + * @param station_id Station ID of the airport. * @return the cost of this operation or an error */ -CommandCost CmdOpenCloseAirport(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdOpenCloseAirport(DoCommandFlag flags, StationID station_id) { - if (!Station::IsValidID(p1)) return CMD_ERROR; - Station *st = Station::Get(p1); + if (!Station::IsValidID(station_id)) return CMD_ERROR; + Station *st = Station::Get(station_id); if (!(st->facilities & FACIL_AIRPORT) || st->owner == OWNER_NONE) return CMD_ERROR; @@ -2512,14 +2464,12 @@ static const byte _dock_h_chk[4] = { 1, 2, 1, 2 }; * Build a dock/haven. * @param flags operation to perform * @param tile tile where dock will be built - * @param p1 (bit 0) - allow docks directly adjacent to other docks. - * @param p2 bit 16-31: station ID to join (NEW_STATION if build new one) - * @param text unused + * @param station_to_join station ID to join (NEW_STATION if build new one) + * @param adjacent allow docks directly adjacent to other docks. * @return the cost of this operation or an error */ -CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_to_join, bool adjacent) { - StationID station_to_join = GB(p2, 16, 16); bool reuse = (station_to_join != NEW_STATION); if (!reuse) station_to_join = INVALID_STATION; bool distant_join = (station_to_join != INVALID_STATION); @@ -2567,7 +2517,7 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* middle */ Station *st = nullptr; - ret = FindJoiningStation(INVALID_STATION, station_to_join, HasBit(p1, 0), dock_area, &st); + ret = FindJoiningStation(INVALID_STATION, station_to_join, adjacent, dock_area, &st); if (ret.Failed()) return ret; /* Distant join */ @@ -3930,15 +3880,13 @@ static bool IsUniqueStationName(const std::string &name) /** * Rename a station * @param flags operation to perform - * @param tile unused - * @param p1 station ID that is to be renamed - * @param p2 unused + * @param station_id station ID that is to be renamed * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameStation(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameStation(DoCommandFlag flags, StationID station_id, const std::string &text) { - Station *st = Station::GetIfValid(p1); + Station *st = Station::GetIfValid(station_id); if (st == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(st->owner); @@ -4244,7 +4192,7 @@ static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_o } else { if (IsDriveThroughStopTile(tile)) { /* Remove the drive-through road stop */ - Command::Do(DC_EXEC | DC_BANKRUPT, tile, 1 | 1 << 8, (GetStationType(tile) == STATION_TRUCK) ? ROADSTOP_TRUCK : ROADSTOP_BUS, {}); + Command::Do(DC_EXEC | DC_BANKRUPT, tile, 1, 1, (GetStationType(tile) == STATION_TRUCK) ? ROADSTOP_TRUCK : ROADSTOP_BUS, false); assert(IsTileType(tile, MP_ROAD)); /* Change owner of tile and all roadtypes */ ChangeTileOwner(tile, old_owner, new_owner); diff --git a/src/station_cmd.h b/src/station_cmd.h index 8e1facc250..6e85ffbfa2 100644 --- a/src/station_cmd.h +++ b/src/station_cmd.h @@ -11,15 +11,18 @@ #define STATION_CMD_H #include "command_type.h" +#include "station_type.h" -CommandProc CmdBuildAirport; -CommandProc CmdBuildDock; -CommandProc CmdBuildRailStation; -CommandProc CmdRemoveFromRailStation; -CommandProc CmdBuildRoadStop; -CommandProc CmdRemoveRoadStop; -CommandProc CmdRenameStation; -CommandProc CmdOpenCloseAirport; +enum StationClassID : byte; + +CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_type, byte layout, StationID station_to_join, bool allow_adjacent); +CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_to_join, bool adjacent); +CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailType rt, Axis axis, byte numtracks, byte plat_len, StationClassID spec_class, byte spec_index, StationID station_to_join, bool adjacent); +CommandCost CmdRemoveFromRailStation(DoCommandFlag flags, TileIndex start, TileIndex end, bool keep_rail); +CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint8 length, RoadStopType stop_type, bool is_drive_through, DiagDirection ddir, RoadType rt, StationID station_to_join, bool adjacent); +CommandCost CmdRemoveRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint height, RoadStopType stop_type, bool remove_road); +CommandCost CmdRenameStation(DoCommandFlag flags, StationID station_id, const std::string &text); +CommandCost CmdOpenCloseAirport(DoCommandFlag flags, StationID station_id); DEF_CMD_TRAIT(CMD_BUILD_AIRPORT, CmdBuildAirport, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_BUILD_DOCK, CmdBuildDock, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 1177e558c1..9233878212 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -1948,7 +1948,7 @@ struct StationViewWindow : public Window { break; case WID_SV_CLOSE_AIRPORT: - Command::Post(0, this->window_number, 0, {}); + Command::Post(this->window_number); break; case WID_SV_TRAINS: // Show list of scheduled trains to this station @@ -2085,7 +2085,7 @@ struct StationViewWindow : public Window { { if (str == nullptr) return; - Command::Post(STR_ERROR_CAN_T_RENAME_STATION, 0, this->window_number, 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_STATION, this->window_number, str); } void OnResize() override diff --git a/src/station_type.h b/src/station_type.h index 36ce7c3ce7..7696c0f087 100644 --- a/src/station_type.h +++ b/src/station_type.h @@ -41,9 +41,10 @@ enum StationType { }; /** Types of RoadStops */ -enum RoadStopType { +enum RoadStopType : byte { ROADSTOP_BUS, ///< A standard stop for buses ROADSTOP_TRUCK, ///< A standard stop for trucks + ROADSTOP_END, ///< End of valid types }; /** The facilities a station might be having */ diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 07c13adcda..3c96f79ad8 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -95,15 +95,12 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile) * Build a ship depot. * @param flags type of operation * @param tile tile where ship depot is built - * @param p1 bit 0 depot orientation (Axis) - * @param p2 unused - * @param text unused + * @param axis depot orientation (Axis) * @return the cost of this operation or an error */ -CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis) { - Axis axis = Extract(p1); - + if (!IsEnumValid(axis)) return CMD_ERROR; TileIndex tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); if (!HasTileWaterGround(tile) || !HasTileWaterGround(tile2)) { diff --git a/src/water_cmd.h b/src/water_cmd.h index ccd18f7639..4d3375aa39 100644 --- a/src/water_cmd.h +++ b/src/water_cmd.h @@ -12,7 +12,7 @@ #include "command_type.h" -CommandProc CmdBuildShipDepot; +CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis); CommandProc CmdBuildCanal; CommandProc CmdBuildLock; diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index a3edf71e89..85c52c98fa 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -164,30 +164,18 @@ extern CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta, * piece of rail * @param flags type of operation * @param start_tile northern most tile where waypoint will be built - * @param p1 various bitstuffed elements - * - p1 = (bit 0- 5) - railtype (not used) - * - p1 = (bit 6) - orientation (Axis) - * - p1 = (bit 8-15) - width of waypoint - * - p1 = (bit 16-23) - height of waypoint - * - p1 = (bit 24) - allow waypoints directly adjacent to other waypoints. - * @param p2 various bitstuffed elements - * - p2 = (bit 0- 7) - custom station class - * - p2 = (bit 8-15) - custom station id - * @param text unused + * @param axis orientation (Axis) + * @param width width of waypoint + * @param height height of waypoint + * @param spec_class custom station class + * @param spec_index custom station id + * @param station_to_join station ID to join (NEW_STATION if build new one) + * @param adjacent allow waypoints directly adjacent to other waypoints. * @return the cost of this operation or an error */ -CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis axis, byte width, byte height, StationClassID spec_class, byte spec_index, StationID station_to_join, bool adjacent) { - /* Unpack parameters */ - Axis axis = Extract(p1); - byte width = GB(p1, 8, 8); - byte height = GB(p1, 16, 8); - bool adjacent = HasBit(p1, 24); - - StationClassID spec_class = Extract(p2); - byte spec_index = GB(p2, 8, 8); - StationID station_to_join = GB(p2, 16, 16); - + if (!IsEnumValid(axis)) return CMD_ERROR; /* Check if the given station class is valid */ if (spec_class != STAT_CLASS_WAYP) return CMD_ERROR; if (spec_index >= StationClass::Get(spec_class)->GetSpecCount()) return CMD_ERROR; @@ -299,12 +287,9 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, uint * Build a buoy. * @param flags operation to perform * @param tile tile where to place the buoy - * @param p1 unused - * @param p2 unused - * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile) { if (tile == 0 || !HasTileWaterGround(tile)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -409,15 +394,13 @@ static bool IsUniqueWaypointName(const std::string &name) /** * Rename a waypoint. * @param flags type of operation - * @param tile unused - * @param p1 id of waypoint - * @param p2 unused + * @param waypoint_id id of waypoint * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameWaypoint(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameWaypoint(DoCommandFlag flags, StationID waypoint_id, const std::string &text) { - Waypoint *wp = Waypoint::GetIfValid(p1); + Waypoint *wp = Waypoint::GetIfValid(waypoint_id); if (wp == nullptr) return CMD_ERROR; if (wp->owner != OWNER_NONE) { diff --git a/src/waypoint_cmd.h b/src/waypoint_cmd.h index 09f7ec5d3e..29855be2c8 100644 --- a/src/waypoint_cmd.h +++ b/src/waypoint_cmd.h @@ -11,11 +11,14 @@ #define WAYPOINT_CMD_H #include "command_type.h" +#include "station_type.h" -CommandProc CmdBuildRailWaypoint; -CommandProc CmdRemoveFromRailWaypoint; -CommandProc CmdBuildBuoy; -CommandProc CmdRenameWaypoint; +enum StationClassID : byte; + +CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis axis, byte width, byte height, StationClassID spec_class, byte spec_index, StationID station_to_join, bool adjacent); +CommandCost CmdRemoveFromRailWaypoint(DoCommandFlag flags, TileIndex start, TileIndex end, bool keep_rail); +CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile); +CommandCost CmdRenameWaypoint(DoCommandFlag flags, StationID waypoint_id, const std::string &text); DEF_CMD_TRAIT(CMD_BUILD_RAIL_WAYPOINT, CmdBuildRailWaypoint, 0, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_REMOVE_FROM_RAIL_WAYPOINT, CmdRemoveFromRailWaypoint, 0, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp index 673601f89f..4fca572242 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.cpp @@ -139,7 +139,7 @@ public: { if (str == nullptr) return; - Command::Post(STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME, 0, this->window_number, 0, str); + Command::Post(STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME, this->window_number, str); } }; From 55170ae703dd2f55ae5c2151aa97dd12da1e917e Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 14 Nov 2021 20:07:23 +0100 Subject: [PATCH 26/60] Codechange: Un-bitstuff rail commands. --- src/rail_cmd.cpp | 251 ++++++++++++--------------------- src/rail_cmd.h | 21 +-- src/rail_gui.cpp | 83 ++++------- src/road_cmd.cpp | 2 +- src/script/api/script_rail.cpp | 48 +++---- src/signal_type.h | 4 +- src/station_cmd.cpp | 2 +- 7 files changed, 153 insertions(+), 258 deletions(-) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 389c44dd98..35c58a1d74 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -429,18 +429,13 @@ static inline bool ValParamTrackOrientation(Track track) * Build a single piece of rail * @param flags operation to perform * @param tile tile to build on - * @param p1 railtype of being built piece (normal, mono, maglev) - * @param p2 various bitstuffed elements - * - (bit 0- 2) - track-orientation, valid values: 0-5 (@see Track) - * - (bit 3) - 0 = error on signal in the way, 1 = auto remove signals when in the way - * @param text unused + * @param railtype railtype of being built piece (normal, mono, maglev) + * @param track track-orientation + * @param auto_remove_signals false = error on signal in the way, true = auto remove signals when in the way * @return the cost of this operation or an error */ -CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType railtype, Track track, bool auto_remove_signals) { - RailType railtype = Extract(p1); - Track track = Extract(p2); - bool auto_remove_signals = HasBit(p2, 3); CommandCost cost(EXPENSES_CONSTRUCTION); if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR; @@ -471,7 +466,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, u for (Track track_it = TRACK_BEGIN; track_it < TRACK_END; track_it++) { if (HasTrack(tile, track_it) && HasSignalOnTrack(tile, track_it)) { - CommandCost ret_remove_signals = Command::Do(flags, tile, track_it, 0, {}); + CommandCost ret_remove_signals = Command::Do(flags, tile, track_it); if (ret_remove_signals.Failed()) return ret_remove_signals; cost.AddCost(ret_remove_signals); } @@ -483,7 +478,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, u * the present rail type are powered on the new rail type. */ if (GetRailType(tile) != railtype && !HasPowerOnRail(railtype, GetRailType(tile))) { if (HasPowerOnRail(GetRailType(tile), railtype)) { - ret = Command::Do(flags, tile, tile, railtype, {}); + ret = Command::Do(flags, tile, tile, railtype, false); if (ret.Failed()) return ret; cost.AddCost(ret); } else { @@ -619,14 +614,11 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, u * Remove a single piece of track * @param flags operation to perform * @param tile tile to remove track from - * @param p1 unused - * @param p2 rail orientation - * @param text unused + * @param track rail orientation * @return the cost of this operation or an error */ -CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, Track track) { - Track track = Extract(p2); CommandCost cost(EXPENSES_CONSTRUCTION); bool crossing = false; @@ -693,7 +685,7 @@ CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, uint32 p1, /* Charge extra to remove signals on the track, if they are there */ if (HasSignalOnTrack(tile, track)) { - cost.AddCost(Command::Do(flags, tile, track, 0, {})); + cost.AddCost(Command::Do(flags, tile, track)); } if (flags & DC_EXEC) { @@ -786,7 +778,7 @@ bool FloodHalftile(TileIndex t) TrackBits to_remove = lower_track & rail_bits; if (to_remove != 0) { Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); - flooded = Command::Do(DC_EXEC, t, 0, FIND_FIRST_BIT(to_remove), {}).Succeeded(); + flooded = Command::Do(DC_EXEC, t, FindFirstTrack(to_remove)).Succeeded(); cur_company.Restore(); if (!flooded) return flooded; // not yet floodable rail_bits = rail_bits & ~to_remove; @@ -876,27 +868,21 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd * Build or remove a stretch of railroad tracks. * @param flags operation to perform * @param tile start tile of drag - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building - * - p2 = (bit 6-8) - track-orientation, valid values: 0-5 (Track enum) - * - p2 = (bit 9) - 0 = build, 1 = remove tracks - * - p2 = (bit 10) - 0 = build up to an obstacle, 1 = fail if an obstacle is found (used for AIs). - * - p2 = (bit 11) - 0 = error on signal in the way, 1 = auto remove signals when in the way - * @param text unused + * @param end_tile end tile of drag + * @param railtype railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building + * @param track track-orientation + * @param remove remove tracks? + * @param auto_remove_signals false = build up to an obstacle, true = fail if an obstacle is found (used for AIs), only used for building + * @param fail_on_obstacle false = error on signal in the way, true = auto remove signals when in the way, only used for building * @return the cost of this operation or an error */ -static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, RailType railtype, Track track, bool remove, bool auto_remove_signals, bool fail_on_obstacle) { CommandCost total_cost(EXPENSES_CONSTRUCTION); - Track track = Extract(p2); - bool remove = HasBit(p2, 9); - bool auto_remove_signals = HasBit(p2, 11); - RailType railtype = Extract(p2); if ((!remove && !ValParamRailtype(railtype)) || !ValParamTrackOrientation(track)) return CMD_ERROR; - if (p1 >= MapSize()) return CMD_ERROR; - TileIndex end_tile = p1; + if (end_tile >= MapSize()) return CMD_ERROR; + Trackdir trackdir = TrackToTrackdir(track); CommandCost ret = ValidateAutoDrag(&trackdir, tile, end_tile); @@ -905,13 +891,12 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, uint3 bool had_success = false; CommandCost last_error = CMD_ERROR; for (;;) { - uint32 p2 = TrackdirToTrack(trackdir) | (auto_remove_signals << 3); - CommandCost ret = remove ? Command::Do(flags, tile, 0, p2, {}) : Command::Do(flags, tile, railtype, p2, {}); + CommandCost ret = remove ? Command::Do(flags, tile, TrackdirToTrack(trackdir)) : Command::Do(flags, tile, railtype, TrackdirToTrack(trackdir), auto_remove_signals); if (ret.Failed()) { last_error = ret; if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) { - if (HasBit(p2, 10)) return last_error; + if (fail_on_obstacle) return last_error; break; } @@ -939,18 +924,17 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, uint3 * Stub for the unified rail builder/remover * @param flags operation to perform * @param tile start tile of drag - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev) - * - p2 = (bit 6-8) - track-orientation, valid values: 0-5 (Track enum) - * - p2 = (bit 9) - 0 = build, 1 = remove tracks - * @param text unused - * @return the cost of this operation or an error + * @param end_tile end tile of drag + * @param railtype railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building + * @param track track-orientation + * @param auto_remove_signals false = build up to an obstacle, true = fail if an obstacle is found (used for AIs). + * @param fail_on_obstacle false = error on signal in the way, true = auto remove signals when in the way + * @see CmdRailTrackHelper */ -CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, RailType railtype, Track track, bool auto_remove_signals, bool fail_on_obstacle) { - return CmdRailTrackHelper(flags, tile, p1, ClrBit(p2, 9), text); + return CmdRailTrackHelper(flags, tile, end_tile, railtype, track, false, auto_remove_signals, fail_on_obstacle); } /** @@ -958,18 +942,14 @@ CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex tile, uint32 p1 * Stub for the unified rail builder/remover * @param flags operation to perform * @param tile start tile of drag - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building - * - p2 = (bit 6-8) - track-orientation, valid values: 0-5 (Track enum) - * - p2 = (bit 9) - 0 = build, 1 = remove tracks - * @param text unused + * @param end_tile end tile of drag + * @param track track-orientation * @return the cost of this operation or an error * @see CmdRailTrackHelper */ -CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, Track track) { - return CmdRailTrackHelper(flags, tile, p1, SetBit(p2, 9), text); + return CmdRailTrackHelper(flags, tile, end_tile, INVALID_RAILTYPE, track, true, false, false); } /** @@ -1037,45 +1017,36 @@ CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType rai /** * Build signals, alternate between double/single, signal/semaphore, * pre/exit/combo-signals, and what-else not. If the rail piece does not - * have any signals, bit 4 (cycle signal-type) is ignored + * have any signals, signal cycling is ignored * @param flags operation to perform * @param tile tile where to build the signals - * @param p1 various bitstuffed elements - * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum) - * - p1 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal or (for bit 7) toggle variant (CTRL-toggle) - * - p1 = (bit 4) - 0 = signals, 1 = semaphores - * - p1 = (bit 5-7) - type of the signal, for valid values see enum SignalType in rail_map.h - * - p1 = (bit 8) - convert the present signal type and variant - * - p1 = (bit 9-11)- start cycle from this signal type - * - p1 = (bit 12-14)-wrap around after this signal type - * - p1 = (bit 15-16)-cycle the signal direction this many times - * - p1 = (bit 17) - 1 = don't modify an existing signal but don't fail either, 0 = always set new signal type - * @param p2 used for CmdBuildManySignals() to copy direction of first signal - * @param text unused + * @param track track-orientation + * @param sigtype type of the signal + * @param sigvar variant of signal type (normal/semaphore) + * @param ctrl_pressed true = override signal/semaphore, or pre/exit/combo signal or toggle variant (CTRL-toggle) + * @param convert_signal convert the present signal type and variant + * @param cycle_start start cycle from this signal type + * @param cycle_stop wrap around after this signal type + * @param num_dir_cycle cycle the signal direction this many times + * @param skip_existing_signals true = don't modify an existing signal but don't fail either, false = always set new signal type + * @param signals_copy used for CmdBuildManySignals() to copy direction of first signal * @return the cost of this operation or an error * @todo p2 should be replaced by two bits for "along" and "against" the track. */ -CommandCost CmdBuildSingleSignal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildSingleSignal(DoCommandFlag flags, TileIndex tile, Track track, SignalType sigtype, SignalVariant sigvar, bool convert_signal, bool skip_existing_signals, bool ctrl_pressed, SignalType cycle_start, SignalType cycle_stop, uint8 num_dir_cycle, byte signals_copy) { - Track track = Extract(p1); - bool ctrl_pressed = HasBit(p1, 3); // was the CTRL button pressed - SignalVariant sigvar = (ctrl_pressed ^ HasBit(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC; // the signal variant of the new signal - SignalType sigtype = Extract(p1); // the signal type of the new signal - bool convert_signal = HasBit(p1, 8); // convert button pressed - SignalType cycle_start = Extract(p1); - SignalType cycle_stop = Extract(p1); - uint num_dir_cycle = GB(p1, 15, 2); - - if (sigtype > SIGTYPE_LAST) return CMD_ERROR; + if (sigtype > SIGTYPE_LAST || sigvar > SIG_SEMAPHORE) return CMD_ERROR; if (cycle_start > cycle_stop || cycle_stop > SIGTYPE_LAST) return CMD_ERROR; + if (ctrl_pressed) sigvar = (SignalVariant)(sigvar ^ SIG_SEMAPHORE); + /* You can only build signals on plain rail tiles, and the selected track must exist */ if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) || !HasTrack(tile, track)) { return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK); } /* Protect against invalid signal copying */ - if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR; + if (signals_copy != 0 && (signals_copy & SignalOnTrack(track)) == 0) return CMD_ERROR; CommandCost ret = CheckTileOwnership(tile); if (ret.Failed()) return ret; @@ -1084,7 +1055,7 @@ CommandCost CmdBuildSingleSignal(DoCommandFlag flags, TileIndex tile, uint32 p1, if (TracksOverlap(GetTrackBits(tile))) return_cmd_error(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK); /* In case we don't want to change an existing signal, return without error. */ - if (HasBit(p1, 17) && HasSignalOnTrack(tile, track)) return CommandCost(); + if (skip_existing_signals && HasSignalOnTrack(tile, track)) return CommandCost(); /* you can not convert a signal if no signal is on track */ if (convert_signal && !HasSignalOnTrack(tile, track)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS); @@ -1094,7 +1065,7 @@ CommandCost CmdBuildSingleSignal(DoCommandFlag flags, TileIndex tile, uint32 p1, /* build new signals */ cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS]); } else { - if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) { + if (signals_copy != 0 && sigvar != GetSignalVariant(tile, track)) { /* convert signals <-> semaphores */ cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] + _price[PR_CLEAR_SIGNALS]); @@ -1136,7 +1107,7 @@ CommandCost CmdBuildSingleSignal(DoCommandFlag flags, TileIndex tile, uint32 p1, /* Subtract old signal infrastructure count. */ Company::Get(GetTileOwner(tile))->infrastructure.signal -= CountBits(GetPresentSignals(tile)); - if (p2 == 0) { + if (signals_copy == 0) { if (!HasSignalOnTrack(tile, track)) { /* build new signals */ SetPresentSignals(tile, GetPresentSignals(tile) | (IsPbsSignal(sigtype) ? KillFirstBit(SignalOnTrack(track)) : SignalOnTrack(track))); @@ -1180,7 +1151,7 @@ CommandCost CmdBuildSingleSignal(DoCommandFlag flags, TileIndex tile, uint32 p1, } else { /* If CmdBuildManySignals is called with copying signals, just copy the * direction of the first signal given as parameter by CmdBuildManySignals */ - SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track))); + SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (signals_copy & SignalOnTrack(track))); SetSignalVariant(tile, track, sigvar); SetSignalType(tile, track, sigtype); } @@ -1257,37 +1228,27 @@ static bool AdvanceSignalAutoFill(TileIndex &tile, Trackdir &trackdir, bool remo * Build many signals by dragging; AutoSignals * @param flags operation to perform * @param tile start tile of drag - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) - * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) - * - p2 = (bit 4) - 0 = signals, 1 = semaphores - * - p2 = (bit 5) - 0 = build, 1 = remove signals - * - p2 = (bit 6) - 0 = selected stretch, 1 = auto fill - * - p2 = (bit 7- 9) - default signal type - * - p2 = (bit 10) - 0 = keep fixed distance, 1 = minimise gaps between signals - * - p2 = (bit 24-31) - user defined signals_density - * @param text unused + * @param end_tile end tile of drag + * @param track track-orientation + * @param sigtype default signal type + * @param sigvar signal variant to build + * @param mode true = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) + * @param remove remove signals? + * @param autofill fill beyond selected stretch? + * @param minimise_gaps false = keep fixed distance, true = minimise gaps between signals + * @param signal_density user defined signals_density * @return the cost of this operation or an error */ -static CommandCost CmdSignalTrackHelper(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +static CommandCost CmdSignalTrackHelper(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, Track track, SignalType sigtype, SignalVariant sigvar, bool mode, bool remove, bool autofill, bool minimise_gaps, int signal_density) { CommandCost total_cost(EXPENSES_CONSTRUCTION); - TileIndex start_tile = tile; - - Track track = Extract(p2); - bool mode = HasBit(p2, 3); - bool semaphores = HasBit(p2, 4); - bool remove = HasBit(p2, 5); - bool autofill = HasBit(p2, 6); - bool minimise_gaps = HasBit(p2, 10); - int signal_density = GB(p2, 24, 8); - if (p1 >= MapSize() || !ValParamTrackOrientation(track)) return CMD_ERROR; - TileIndex end_tile = p1; + if (end_tile >= MapSize() || !ValParamTrackOrientation(track)) return CMD_ERROR; if (signal_density == 0 || signal_density > 20) return CMD_ERROR; + if (!remove && (sigtype > SIGTYPE_LAST || sigvar > SIG_SEMAPHORE)) return CMD_ERROR; if (!IsPlainRailTile(tile)) return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK); + TileIndex start_tile = tile; /* Interpret signal_density as the logical length of said amount of tiles in X/Y direction. */ signal_density *= TILE_AXIAL_DISTANCE; @@ -1302,9 +1263,6 @@ static CommandCost CmdSignalTrackHelper(DoCommandFlag flags, TileIndex tile, uin /* Must start on a valid track to be able to avoid loops */ if (!HasTrack(tile, track)) return CMD_ERROR; - SignalType sigtype = (SignalType)GB(p2, 7, 3); - if (sigtype > SIGTYPE_LAST) return CMD_ERROR; - byte signals; /* copy the signal-style of the first rail-piece if existing */ if (HasSignalOnTrack(tile, track)) { @@ -1312,7 +1270,7 @@ static CommandCost CmdSignalTrackHelper(DoCommandFlag flags, TileIndex tile, uin assert(signals != 0); /* copy signal/semaphores style (independent of CTRL) */ - semaphores = GetSignalVariant(tile, track) != SIG_ELECTRIC; + sigvar = GetSignalVariant(tile, track); sigtype = GetSignalType(tile, track); /* Don't but copy entry or exit-signal type */ @@ -1344,22 +1302,14 @@ static CommandCost CmdSignalTrackHelper(DoCommandFlag flags, TileIndex tile, uin Trackdir last_suitable_trackdir = INVALID_TRACKDIR; CommandCost last_error = CMD_ERROR; bool had_success = false; - uint32 param1 = 0; - SB(param1, 3, 1, mode); - SB(param1, 4, 1, semaphores); - SB(param1, 5, 3, sigtype); - auto build_signal = [&](TileIndex tile, Trackdir trackdir, bool test_only) { - SB(param1, 0, 3, TrackdirToTrack(trackdir)); - SB(param1, 17, 1, (!remove && signal_ctr == 0 ? 1 : 0)); - /* Pick the correct orientation for the track direction */ byte signals = 0; if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(trackdir); if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(trackdir); DoCommandFlag do_flags = test_only ? flags & ~DC_EXEC : flags; - CommandCost ret = remove ? Command::Do(do_flags, tile, param1, signals, {}) : Command::Do(do_flags, tile, param1, signals, {}); + CommandCost ret = remove ? Command::Do(do_flags, tile, TrackdirToTrack(trackdir)) : Command::Do(do_flags, tile, TrackdirToTrack(trackdir), sigtype, sigvar, false, signal_ctr == 0, mode, SIGTYPE_NORMAL, SIGTYPE_NORMAL, 0, signals); if (test_only) return ret.Succeeded(); @@ -1469,40 +1419,31 @@ static CommandCost CmdSignalTrackHelper(DoCommandFlag flags, TileIndex tile, uin * Stub for the unified signal builder/remover * @param flags operation to perform * @param tile start tile of drag - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) - * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) - * - p2 = (bit 4) - 0 = signals, 1 = semaphores - * - p2 = (bit 5) - 0 = build, 1 = remove signals - * - p2 = (bit 6) - 0 = selected stretch, 1 = auto fill - * - p2 = (bit 7- 9) - default signal type - * - p2 = (bit 24-31) - user defined signals_density - * @param text unused + * @param end_tile end tile of drag + * @param track track-orientation + * @param sigtype default signal type + * @param sigvar signal variant to build + * @param mode true = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) + * @param autofill fill beyond selected stretch? + * @param minimise_gaps false = keep fixed distance, true = minimise gaps between signals + * @param signal_density user defined signals_density * @return the cost of this operation or an error * @see CmdSignalTrackHelper */ -CommandCost CmdBuildSignalTrack(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildSignalTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, Track track, SignalType sigtype, SignalVariant sigvar, bool mode, bool autofill, bool minimise_gaps, byte signal_density) { - return CmdSignalTrackHelper(flags, tile, p1, p2, text); + return CmdSignalTrackHelper(flags, tile, end_tile, track, sigtype, sigvar, mode, false, autofill, minimise_gaps, signal_density); } /** * Remove signals * @param flags operation to perform * @param tile coordinates where signal is being deleted from - * @param p1 various bitstuffed elements, only track information is used - * - (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) - * - (bit 3) - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) - * - (bit 4) - 0 = signals, 1 = semaphores - * @param p2 unused - * @param text unused + * @param track track-orientation * @return the cost of this operation or an error */ -CommandCost CmdRemoveSingleSignal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveSingleSignal(DoCommandFlag flags, TileIndex tile, Track track) { - Track track = Extract(p1); - if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) || !HasTrack(tile, track)) { return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK); } @@ -1561,22 +1502,15 @@ CommandCost CmdRemoveSingleSignal(DoCommandFlag flags, TileIndex tile, uint32 p1 * Stub for the unified signal builder/remover * @param flags operation to perform * @param tile start tile of drag - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0- 2) - track-orientation, valid values: 0-5 (Track enum) - * - p2 = (bit 3) - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle) - * - p2 = (bit 4) - 0 = signals, 1 = semaphores - * - p2 = (bit 5) - 0 = build, 1 = remove signals - * - p2 = (bit 6) - 0 = selected stretch, 1 = auto fill - * - p2 = (bit 7- 9) - default signal type - * - p2 = (bit 24-31) - user defined signals_density - * @param text unused + * @param end_tile end tile of drag + * @param track track-orientation + * @param autofill fill beyond selected stretch? * @return the cost of this operation or an error * @see CmdSignalTrackHelper */ -CommandCost CmdRemoveSignalTrack(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveSignalTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, Track track, bool autofill) { - return CmdSignalTrackHelper(flags, tile, p1, SetBit(p2, 5), text); // bit 5 is remove bit + return CmdSignalTrackHelper(flags, tile, end_tile, track, SIGTYPE_NORMAL, SIG_ELECTRIC, false, true, autofill, false, 1); // bit 5 is remove bit } /** Update power of train under which is the railtype being converted */ @@ -1595,19 +1529,14 @@ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data) * monorail/maglev easily or vice-versa. * @param flags operation to perform * @param tile end tile of rail conversion drag - * @param p1 start tile of drag - * @param p2 various bitstuffed elements: - * - p2 = (bit 0- 5) new railtype to convert to. - * - p2 = (bit 6) build diagonally or not. - * @param text unused + * @param area_start start tile of drag + * @param totype new railtype to convert to. + * @param diagonal build diagonally or not. * @return the cost of this operation or an error */ -CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_start, RailType totype, bool diagonal) { - RailType totype = Extract(p2); - TileIndex area_start = p1; TileIndex area_end = tile; - bool diagonal = HasBit(p2, 6); if (!ValParamRailtype(totype)) return CMD_ERROR; if (area_start >= MapSize()) return CMD_ERROR; @@ -1879,7 +1808,7 @@ static CommandCost ClearTile_Track(TileIndex tile, DoCommandFlag flags) TrackBits tracks = GetTrackBits(tile); while (tracks != TRACK_BIT_NONE) { Track track = RemoveFirstTrack(&tracks); - CommandCost ret = Command::Do(flags, tile, 0, track, {}); + CommandCost ret = Command::Do(flags, tile, track); if (ret.Failed()) return ret; cost.AddCost(ret); } diff --git a/src/rail_cmd.h b/src/rail_cmd.h index 31266e2b03..2299435c20 100644 --- a/src/rail_cmd.h +++ b/src/rail_cmd.h @@ -11,17 +11,20 @@ #define RAIL_CMD_H #include "command_type.h" +#include "track_type.h" +#include "rail_type.h" +#include "signal_type.h" -CommandProc CmdBuildRailroadTrack; -CommandProc CmdRemoveRailroadTrack; -CommandProc CmdBuildSingleRail; -CommandProc CmdRemoveSingleRail; +CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, RailType railtype, Track track, bool auto_remove_signals, bool fail_on_obstacle); +CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, Track track); +CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType railtype, Track track, bool auto_remove_signals); +CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, Track track); CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir); -CommandProc CmdBuildSingleSignal; -CommandProc CmdRemoveSingleSignal; -CommandProc CmdConvertRail; -CommandProc CmdBuildSignalTrack; -CommandProc CmdRemoveSignalTrack; +CommandCost CmdBuildSingleSignal(DoCommandFlag flags, TileIndex tile, Track track, SignalType sigtype, SignalVariant sigvar, bool convert_signal, bool skip_existing_signals, bool ctrl_pressed, SignalType cycle_start, SignalType cycle_stop, uint8 num_dir_cycle, byte signals_copy); +CommandCost CmdRemoveSingleSignal(DoCommandFlag flags, TileIndex tile, Track track); +CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_start, RailType totype, bool diagonal); +CommandCost CmdBuildSignalTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, Track track, SignalType sigtype, SignalVariant sigvar, bool mode, bool autofill, bool minimise_gaps, byte signal_density); +CommandCost CmdRemoveSignalTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, Track track, bool autofill); DEF_CMD_TRAIT(CMD_BUILD_RAILROAD_TRACK, CmdBuildRailroadTrack, CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_REMOVE_RAILROAD_TRACK, CmdRemoveRailroadTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 60ac12c726..a8e8b68b42 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -94,14 +94,14 @@ void CcPlaySound_CONSTRUCTION_RAIL(Commands cmd, const CommandCost &result,TileI if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); } -static void GenericPlaceRail(TileIndex tile, int cmd) +static void GenericPlaceRail(TileIndex tile, Track track) { if (_remove_button_clicked) { Command::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, - tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3), {}); + tile, track); } else { Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, - tile, _cur_railtype, cmd | (_settings_client.gui.auto_remove_signals << 3), {}); + tile, _cur_railtype, track, _settings_client.gui.auto_remove_signals); } } @@ -118,7 +118,7 @@ static void PlaceExtraDepotRail(TileIndex tile, DiagDirection dir, Track track) if (GetRailTileType(tile) == RAIL_TILE_SIGNALS && !_settings_client.gui.auto_remove_signals) return; if ((GetTrackBits(tile) & DiagdirReachesTracks(dir)) == 0) return; - Command::Post(tile, _cur_railtype, track | (_settings_client.gui.auto_remove_signals << 3), {}); + Command::Post(tile, _cur_railtype, track, _settings_client.gui.auto_remove_signals); } /** Additional pieces of track to add at the entrance of a depot. */ @@ -240,39 +240,21 @@ static void GenericPlaceSignals(TileIndex tile) Track track = FindFirstTrack(trackbits); if (_remove_button_clicked) { - Command::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, tile, track, 0, {}); + Command::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, tile, track); } else { - const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0); - - /* various bitstuffed elements for CmdBuildSingleSignal() */ - uint32 p1 = track; - /* Which signals should we cycle through? */ - uint8 cycle_types; - - if (_settings_client.gui.cycle_signal_types == SIGNAL_CYCLE_ALL && _settings_client.gui.signal_gui_mode == SIGNAL_GUI_ALL) { - cycle_types = SIGTYPE_NORMAL | (SIGTYPE_LAST << 3); - } else { - cycle_types = SIGTYPE_PBS | (SIGTYPE_LAST << 3); - } + SignalType cycle_start = _settings_client.gui.cycle_signal_types == SIGNAL_CYCLE_ALL && _settings_client.gui.signal_gui_mode == SIGNAL_GUI_ALL ? SIGTYPE_NORMAL : SIGTYPE_PBS; - if (w != nullptr) { + if (FindWindowById(WC_BUILD_SIGNAL, 0) != nullptr) { /* signal GUI is used */ - SB(p1, 3, 1, _ctrl_pressed); - SB(p1, 4, 1, _cur_signal_variant); - SB(p1, 5, 3, _cur_signal_type); - SB(p1, 8, 1, _convert_signal_button); - SB(p1, 9, 6, cycle_types); + Command::Post(_convert_signal_button ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL, + tile, track, _cur_signal_type, _cur_signal_variant, _convert_signal_button, false, _ctrl_pressed, cycle_start, SIGTYPE_LAST, 0, 0); } else { - SB(p1, 3, 1, _ctrl_pressed); - SB(p1, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC)); - SB(p1, 5, 3, SIGTYPE_PBS_ONEWAY); - SB(p1, 8, 1, 0); - SB(p1, 9, 6, cycle_types); - } + SignalVariant sigvar = _cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC; + Command::Post(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL, + tile, track, SIGTYPE_PBS_ONEWAY, sigvar, false, false, _ctrl_pressed, cycle_start, SIGTYPE_LAST, 0, 0); - Command::Post((w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, - CcPlaySound_CONSTRUCTION_RAIL, tile, p1, 0, {}); + } } } @@ -371,21 +353,20 @@ static void BuildRailClick_Remove(Window *w) } } -static void DoRailroadTrack(int mode) +static void DoRailroadTrack(Track track) { - uint32 p2 = _cur_railtype | (mode << 6) | (_settings_client.gui.auto_remove_signals << 11); if (_remove_button_clicked) { Command::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), track); } else { Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype, track, _settings_client.gui.auto_remove_signals, false); } } static void HandleAutodirPlacement() { - int trackstat = _thd.drawstyle & HT_DIR_MASK; // 0..5 + Track trackstat = static_cast( _thd.drawstyle & HT_DIR_MASK); // 0..5 if (_thd.drawstyle & HT_RAIL) { // one tile case GenericPlaceRail(TileVirtXY(_thd.selend.x, _thd.selend.y), trackstat); @@ -403,40 +384,24 @@ static void HandleAutodirPlacement() */ static void HandleAutoSignalPlacement() { - uint32 p2 = GB(_thd.drawstyle, 0, 3); // 0..5 + Track track = (Track)GB(_thd.drawstyle, 0, 3); // 0..5 if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT) { // one tile case GenericPlaceSignals(TileVirtXY(_thd.selend.x, _thd.selend.y)); return; } - const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0); - - if (w != nullptr) { - /* signal GUI is used */ - SB(p2, 3, 1, 0); - SB(p2, 4, 1, _cur_signal_variant); - SB(p2, 6, 1, _ctrl_pressed); - SB(p2, 7, 3, _cur_signal_type); - SB(p2, 24, 8, _settings_client.gui.drag_signals_density); - SB(p2, 10, 1, !_settings_client.gui.drag_signals_fixed_distance); - } else { - SB(p2, 3, 1, 0); - SB(p2, 4, 1, (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC)); - SB(p2, 6, 1, _ctrl_pressed); - SB(p2, 7, 3, SIGTYPE_PBS_ONEWAY); - SB(p2, 24, 8, _settings_client.gui.drag_signals_density); - SB(p2, 10, 1, !_settings_client.gui.drag_signals_fixed_distance); - } - /* _settings_client.gui.drag_signals_density is given as a parameter such that each user * in a network game can specify their own signal density */ if (_remove_button_clicked) { Command::Post(STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM, CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), track, _ctrl_pressed); } else { + bool sig_gui = FindWindowById(WC_BUILD_SIGNAL, 0) != nullptr; + SignalType sigtype = sig_gui ? _cur_signal_type : SIGTYPE_PBS_ONEWAY; + SignalVariant sigvar = sig_gui ? _cur_signal_variant : (_cur_year < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC); Command::Post(STR_ERROR_CAN_T_BUILD_SIGNALS_HERE, CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), p2, {}); + TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), track, sigtype, sigvar, false, _ctrl_pressed, !_settings_client.gui.drag_signals_fixed_distance, _settings_client.gui.drag_signals_density); } } @@ -725,7 +690,7 @@ struct BuildRailToolbarWindow : Window { break; case DDSP_CONVERT_RAIL: - Command::Post(STR_ERROR_CAN_T_CONVERT_RAIL, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 1 << 6 : 0), {}); + Command::Post(STR_ERROR_CAN_T_CONVERT_RAIL, CcPlaySound_CONSTRUCTION_RAIL, end_tile, start_tile, _cur_railtype, _ctrl_pressed); break; case DDSP_REMOVE_STATION: diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 72dcb5276e..ece49676be 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -2229,7 +2229,7 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne if (IsLevelCrossing(tile)) { if (GetTileOwner(tile) == old_owner) { if (new_owner == INVALID_OWNER) { - Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, GetCrossingRailTrack(tile), {}); + Command::Do(DC_EXEC | DC_BANKRUPT, tile, GetCrossingRailTrack(tile)); } else { /* Update infrastructure counts. No need to dirty windows here, we'll redraw the whole screen anyway. */ Company::Get(old_owner)->infrastructure.rail[GetRailType(tile)] -= LEVELCROSSING_TRACKBIT_FACTOR; diff --git a/src/script/api/script_rail.cpp b/src/script/api/script_rail.cpp index 30a1085d48..4dc06553d0 100644 --- a/src/script/api/script_rail.cpp +++ b/src/script/api/script_rail.cpp @@ -116,7 +116,7 @@ EnforcePrecondition(false, ::IsValidTile(end_tile)); EnforcePrecondition(false, IsRailTypeAvailable(convert_to)); - return ScriptObject::Command::Do(start_tile, end_tile, convert_to, {}); + return ScriptObject::Command::Do(start_tile, end_tile, (::RailType)convert_to, false); } /* static */ TileIndex ScriptRail::GetRailDepotFrontTile(TileIndex depot) @@ -253,7 +253,7 @@ EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); - return ScriptObject::Command::Do(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 6), {}); + return ScriptObject::Command::Do(tile, tile, (::RailType)GetCurrentRailType(), FindFirstTrack((::TrackBits)rail_track), false, false); } /* static */ bool ScriptRail::RemoveRailTrack(TileIndex tile, RailTrack rail_track) @@ -264,7 +264,7 @@ EnforcePrecondition(false, GetRailTracks(tile) & rail_track); EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0); - return ScriptObject::Command::Do(tile, tile, FindFirstTrack((::TrackBits)rail_track) << 6, {}); + return ScriptObject::Command::Do(tile, tile, FindFirstTrack((::TrackBits)rail_track)); } /* static */ bool ScriptRail::AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to) @@ -292,21 +292,21 @@ * Prepare the second parameter for CmdBuildRailroadTrack and CmdRemoveRailroadTrack. The direction * depends on all three tiles. Sometimes the third tile needs to be adjusted. */ -static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) +static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) { int diag_offset = abs(abs((int)::TileX(*to) - (int)::TileX(tile)) - abs((int)::TileY(*to) - (int)::TileY(tile))); - uint32 p2 = 0; + Track track = TRACK_BEGIN; if (::TileY(from) == ::TileY(*to)) { - p2 |= (TRACK_X << 6); + track = TRACK_X; *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); } else if (::TileX(from) == ::TileX(*to)) { - p2 |= (TRACK_Y << 6); + track = TRACK_Y; *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); } else if (::TileY(from) < ::TileY(tile)) { if (::TileX(*to) < ::TileX(tile)) { - p2 |= (TRACK_UPPER << 6); + track = TRACK_UPPER; } else { - p2 |= (TRACK_LEFT << 6); + track = TRACK_LEFT; } if (diag_offset != 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); @@ -315,9 +315,9 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) } } else if (::TileY(from) > ::TileY(tile)) { if (::TileX(*to) < ::TileX(tile)) { - p2 |= (TRACK_RIGHT << 6); + track = TRACK_RIGHT; } else { - p2 |= (TRACK_LOWER << 6); + track = TRACK_LOWER; } if (diag_offset != 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); @@ -326,9 +326,9 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) } } else if (::TileX(from) < ::TileX(tile)) { if (::TileY(*to) < ::TileY(tile)) { - p2 |= (TRACK_UPPER << 6); + track = TRACK_UPPER; } else { - p2 |= (TRACK_RIGHT << 6); + track = TRACK_RIGHT; } if (diag_offset == 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); @@ -337,9 +337,9 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) } } else if (::TileX(from) > ::TileX(tile)) { if (::TileY(*to) < ::TileY(tile)) { - p2 |= (TRACK_LEFT << 6); + track = TRACK_LEFT; } else { - p2 |= (TRACK_LOWER << 6); + track = TRACK_LOWER; } if (diag_offset == 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); @@ -347,7 +347,7 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); } } - return p2; + return track; } /* static */ bool ScriptRail::BuildRail(TileIndex from, TileIndex tile, TileIndex to) @@ -364,8 +364,8 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) (::TileX(from) == ::TileX(tile) && ::TileX(tile) == ::TileX(to)) || (::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to))); - uint32 p2 = SimulateDrag(from, tile, &to) | 1 << 10 | ScriptRail::GetCurrentRailType();; - return ScriptObject::Command::Do(tile, to, p2, {}); + Track track = SimulateDrag(from, tile, &to); + return ScriptObject::Command::Do(tile, to, (::RailType)ScriptRail::GetCurrentRailType(), track, false, true); } /* static */ bool ScriptRail::RemoveRail(TileIndex from, TileIndex tile, TileIndex to) @@ -381,8 +381,8 @@ static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) (::TileX(from) == ::TileX(tile) && ::TileX(tile) == ::TileX(to)) || (::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to))); - uint32 p2 = SimulateDrag(from, tile, &to); - return ScriptObject::Command::Do(tile, to, p2, {}); + Track track = SimulateDrag(from, tile, &to); + return ScriptObject::Command::Do(tile, to, track); } /** @@ -461,14 +461,12 @@ static bool IsValidSignalType(int signal_type) } EnforcePrecondition(false, track != INVALID_TRACK); - uint p1 = track; if (signal < SIGNALTYPE_TWOWAY) { if (signal != SIGNALTYPE_PBS && signal != SIGNALTYPE_PBS_ONEWAY) signal_cycles++; - p1 |= (signal_cycles << 15); } - p1 |= ((signal >= SIGNALTYPE_TWOWAY ? signal ^ SIGNALTYPE_TWOWAY : signal) << 5); + ::SignalType sig_type = (::SignalType)(signal >= SIGNALTYPE_TWOWAY ? signal ^ SIGNALTYPE_TWOWAY : signal); - return ScriptObject::Command::Do(tile, p1, 0, {}); + return ScriptObject::Command::Do(tile, track, sig_type, ::SIG_ELECTRIC, false, false, false, ::SIGTYPE_NORMAL, ::SIGTYPE_NORMAL, signal_cycles, 0); } /* static */ bool ScriptRail::RemoveSignal(TileIndex tile, TileIndex front) @@ -487,7 +485,7 @@ static bool IsValidSignalType(int signal_type) } EnforcePrecondition(false, track != INVALID_TRACK); - return ScriptObject::Command::Do(tile, track, 0, {}); + return ScriptObject::Command::Do(tile, track); } /* static */ Money ScriptRail::GetBuildCost(RailType railtype, BuildType build_type) diff --git a/src/signal_type.h b/src/signal_type.h index 5af2a2c94a..ff5dd3b553 100644 --- a/src/signal_type.h +++ b/src/signal_type.h @@ -13,14 +13,14 @@ #include "core/enum_type.hpp" /** Variant of the signal, i.e. how does the signal look? */ -enum SignalVariant { +enum SignalVariant : byte { SIG_ELECTRIC = 0, ///< Light signal SIG_SEMAPHORE = 1, ///< Old-fashioned semaphore signal }; /** Type of signal, i.e. how does the signal behave? */ -enum SignalType { +enum SignalType : byte { SIGTYPE_NORMAL = 0, ///< normal signal SIGTYPE_ENTRY = 1, ///< presignal block entry SIGTYPE_EXIT = 2, ///< presignal block exit diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index bdc58588b9..6424a73e15 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -925,7 +925,7 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl affected_vehicles.push_back(v); } } - CommandCost ret = Command::Do(flags, tile_cur, 0, track, {}); + CommandCost ret = Command::Do(flags, tile_cur, track); if (ret.Failed()) return ret; cost.AddCost(ret); /* With flags & ~DC_EXEC CmdLandscapeClear would fail since the rail still exists */ From 46bd2f1cedde365218a3f1a52116fe169587af89 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Mon, 15 Nov 2021 00:03:01 +0100 Subject: [PATCH 27/60] Codechange: Un-bitstuff remaining transport infrastructure commands. --- src/bridge_gui.cpp | 38 ++++----- src/dock_gui.cpp | 8 +- src/rail_gui.cpp | 4 +- src/road_cmd.cpp | 130 ++++++++++++------------------- src/road_cmd.h | 8 +- src/road_gui.cpp | 75 +++++++----------- src/road_map.h | 13 +--- src/road_type.h | 16 +++- src/roadveh_cmd.cpp | 2 +- src/script/api/script_bridge.cpp | 27 ++----- src/script/api/script_marine.cpp | 4 +- src/script/api/script_road.cpp | 9 ++- src/script/api/script_tunnel.cpp | 23 ++---- src/town_cmd.cpp | 16 ++-- src/transport_type.h | 2 +- src/tunnelbridge_cmd.cpp | 40 ++++------ src/tunnelbridge_cmd.h | 6 +- src/water_cmd.cpp | 26 +++---- src/water_cmd.h | 5 +- src/water_map.h | 2 +- 20 files changed, 180 insertions(+), 274 deletions(-) diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 38ff698eb6..77261932b3 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -60,16 +60,14 @@ void CcBuildBridge(Commands cmd, const CommandCost &result, TileIndex end_tile, if (result.Failed()) return; if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile); - auto [tile, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); - - TransportType transport_type = Extract(p2); + auto [tile, tile_start, transport_type, bridge_type, road_rail_type] = EndianBufferReader::ToValue::Args>(data); if (transport_type == TRANSPORT_ROAD) { DiagDirection end_direction = ReverseDiagDir(GetTunnelBridgeDirection(end_tile)); ConnectRoadToStructure(end_tile, end_direction); - DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(p1)); - ConnectRoadToStructure(p1, start_direction); + DiagDirection start_direction = ReverseDiagDir(GetTunnelBridgeDirection(tile_start)); + ConnectRoadToStructure(tile_start, start_direction); } } @@ -86,7 +84,8 @@ private: /* Internal variables */ TileIndex start_tile; TileIndex end_tile; - uint32 type; + TransportType transport_type; + byte road_rail_type; GUIBridgeList *bridges; int bridgetext_offset; ///< Horizontal offset of the text describing the bridge properties in #WID_BBS_BRIDGE_LIST relative to the left edge. Scrollbar *vscroll; @@ -111,13 +110,13 @@ private: void BuildBridge(uint8 i) { - switch ((TransportType)(this->type >> 15)) { + switch (this->transport_type) { case TRANSPORT_RAIL: _last_railbridge_type = this->bridges->at(i).index; break; case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->at(i).index; break; default: break; } Command::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, - this->end_tile, this->start_tile, this->type | this->bridges->at(i).index, {}); + this->end_tile, this->start_tile, this->transport_type, this->bridges->at(i).index, this->road_rail_type); } /** Sort the builable bridges */ @@ -134,19 +133,20 @@ private: } public: - BuildBridgeWindow(WindowDesc *desc, TileIndex start, TileIndex end, uint32 br_type, GUIBridgeList *bl) : Window(desc), + BuildBridgeWindow(WindowDesc *desc, TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type, GUIBridgeList *bl) : Window(desc), start_tile(start), end_tile(end), - type(br_type), + transport_type(transport_type), + road_rail_type(road_rail_type), bridges(bl) { this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_BBS_SCROLLBAR); /* Change the data, or the caption of the gui. Set it to road or rail, accordingly. */ - this->GetWidget(WID_BBS_CAPTION)->widget_data = (GB(this->type, 15, 2) == TRANSPORT_ROAD) ? STR_SELECT_ROAD_BRIDGE_CAPTION : STR_SELECT_RAIL_BRIDGE_CAPTION; - this->FinishInitNested(GB(br_type, 15, 2)); // Initializes 'this->bridgetext_offset'. + this->GetWidget(WID_BBS_CAPTION)->widget_data = (transport_type == TRANSPORT_ROAD) ? STR_SELECT_ROAD_BRIDGE_CAPTION : STR_SELECT_RAIL_BRIDGE_CAPTION; + this->FinishInitNested(transport_type); // Initializes 'this->bridgetext_offset'. - this->parent = FindWindowById(WC_BUILD_TOOLBAR, GB(this->type, 15, 2)); + this->parent = FindWindowById(WC_BUILD_TOOLBAR, transport_type); this->bridges->SetListing(this->last_sorting); this->bridges->SetSortFuncs(this->sorter_funcs); this->bridges->NeedResort(); @@ -361,12 +361,6 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo { CloseWindowByClass(WC_BUILD_BRIDGE); - /* Data type for the bridge. - * Bit 16,15 = transport type, - * 14..8 = road/rail types, - * 7..0 = type of bridge */ - uint32 type = (transport_type << 15) | (road_rail_type << 8); - /* The bridge length without ramps. */ const uint bridge_len = GetTunnelBridgeLength(start, end); @@ -382,14 +376,14 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo default: break; // water ways and air routes don't have bridge types } if (_ctrl_pressed && CheckBridgeAvailability(last_bridge_type, bridge_len).Succeeded()) { - Command::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, type | last_bridge_type, {}); + Command::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, transport_type, last_bridge_type, road_rail_type); return; } /* only query bridge building possibility once, result is the same for all bridges! * returns CMD_ERROR on failure, and price on success */ StringID errmsg = INVALID_STRING_ID; - CommandCost ret = Command::Do(CommandFlagsToDCFlags(GetCommandFlags()) | DC_QUERY_COST, end, start, type, {}); + CommandCost ret = Command::Do(CommandFlagsToDCFlags(GetCommandFlags()) | DC_QUERY_COST, end, start, transport_type, 0, road_rail_type); GUIBridgeList *bl = nullptr; if (ret.Failed()) { @@ -449,7 +443,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo } if (bl != nullptr && bl->size() != 0) { - new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl); + new BuildBridgeWindow(&_build_bridge_desc, start, end, transport_type, road_rail_type, bl); } else { delete bl; ShowErrorMessage(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, errmsg, WL_INFO, TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE); diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index cdcb4ea84a..d8cd7c5d46 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -196,7 +196,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_LOCK: // Build lock button - Command::Post(STR_ERROR_CAN_T_BUILD_LOCKS, CcBuildDocks, tile, 0, 0, {}); + Command::Post(STR_ERROR_CAN_T_BUILD_LOCKS, CcBuildDocks, tile); break; case WID_DT_DEMOLISH: // Demolish aka dynamite button @@ -234,7 +234,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button - Command::Post(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER << 15, {}); + Command::Post(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER, 0, 0); break; default: NOT_REACHED(); @@ -254,10 +254,10 @@ struct BuildDocksToolbarWindow : Window { GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; case DDSP_CREATE_WATER: - Command::Post(STR_ERROR_CAN_T_BUILD_CANALS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL, {}); + Command::Post(STR_ERROR_CAN_T_BUILD_CANALS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, (_game_mode == GM_EDITOR && _ctrl_pressed) ? WATER_CLASS_SEA : WATER_CLASS_CANAL, false); break; case DDSP_CREATE_RIVER: - Command::Post(STR_ERROR_CAN_T_PLACE_RIVERS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0), {}); + Command::Post(STR_ERROR_CAN_T_PLACE_RIVERS, CcPlaySound_CONSTRUCTION_WATER, end_tile, start_tile, WATER_CLASS_RIVER, _ctrl_pressed); break; default: break; diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index a8e8b68b42..bac59d7474 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -648,7 +648,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_TUNNEL: - Command::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, {}); + Command::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, TRANSPORT_RAIL, _cur_railtype); break; case WID_RAT_CONVERT_RAIL: @@ -746,7 +746,7 @@ struct BuildRailToolbarWindow : Window { void OnPlacePresize(Point pt, TileIndex tile) override { - Command::Do(DC_AUTO, tile, _cur_railtype | (TRANSPORT_RAIL << 8), 0, {}); + Command::Do(DC_AUTO, tile, TRANSPORT_RAIL, _cur_railtype); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index ece49676be..e160a2b842 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -606,14 +606,13 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existi * Build a piece of road. * @param flags operation to perform * @param tile tile where to build road - * @param p1 bit 0..3 road pieces to build (RoadBits) - * bit 4..9 road type - * bit 11..12 disallowed directions to toggle - * @param p2 the town that is building the road (0 if not applicable) - * @param text unused + * @param pieces road pieces to build (RoadBits) + * @param rt road type + * @param toggle_drd disallowed directions to toggle + * @param town_id the town that is building the road (0 if not applicable) * @return the cost of this operation or an error */ -CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, RoadType rt, DisallowedRoadDirections toggle_drd, TownID town_id) { CompanyID company = _current_company; CommandCost cost(EXPENSES_CONSTRUCTION); @@ -623,10 +622,10 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero * if a non-company is building the road */ - if ((Company::IsValidID(company) && p2 != 0) || (company == OWNER_TOWN && !Town::IsValidID(p2)) || (company == OWNER_DEITY && p2 != 0)) return CMD_ERROR; + if ((Company::IsValidID(company) && town_id != 0) || (company == OWNER_TOWN && !Town::IsValidID(town_id)) || (company == OWNER_DEITY && town_id != 0)) return CMD_ERROR; if (company != OWNER_TOWN) { const Town *town = CalcClosestTownFromTile(tile); - p2 = (town != nullptr) ? town->index : INVALID_TOWN; + town_id = (town != nullptr) ? town->index : INVALID_TOWN; if (company == OWNER_DEITY) { company = OWNER_TOWN; @@ -638,16 +637,10 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 } } - RoadBits pieces = Extract(p1); - /* do not allow building 'zero' road bits, code wouldn't handle it */ - if (pieces == ROAD_NONE) return CMD_ERROR; - - RoadType rt = Extract(p1); + if (pieces == ROAD_NONE || !IsEnumValid(pieces) || !IsEnumValid(toggle_drd)) return CMD_ERROR; if (!ValParamRoadType(rt)) return CMD_ERROR; - DisallowedRoadDirections toggle_drd = Extract(p1); - Slope tileh = GetTileSlope(tile); RoadTramType rtt = GetRoadTramType(rt); @@ -785,7 +778,7 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Always add road to the roadtypes (can't draw without it) */ bool reserved = HasBit(GetRailReservationTrackBits(tile), railtrack); - MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2); + MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id); SetCrossingReservation(tile, reserved); UpdateLevelCrossing(tile, false); MarkTileDirtyByTile(tile); @@ -870,7 +863,7 @@ do_clear:; if (HasPowerOnRoad(rt, existing_rt)) { rt = existing_rt; } else if (HasPowerOnRoad(existing_rt, rt)) { - CommandCost ret = Command::Do(flags, tile, tile, rt, {}); + CommandCost ret = Command::Do(flags, tile, tile, rt); if (ret.Failed()) return ret; cost.AddCost(ret); } else { @@ -895,7 +888,7 @@ do_clear:; if (existing == ROAD_NONE || rttype == ROAD_TILE_CROSSING) { SetRoadType(tile, rtt, rt); SetRoadOwner(tile, rtt, company); - if (rtt == RTT_ROAD) SetTownIndex(tile, p2); + if (rtt == RTT_ROAD) SetTownIndex(tile, town_id); } if (rttype != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rtt); break; @@ -927,7 +920,7 @@ do_clear:; } default: - MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2, company, company); + MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id, company, company); break; } @@ -971,49 +964,40 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir) * Build a long piece of road. * @param flags operation to perform * @param start_tile start tile of drag (the building cost will appear over this tile) - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1). Only used if bit 6 is set or if we are building a single tile - * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2). Only used if bit 6 is set or if we are building a single tile - * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) - * - p2 = (bit 3..8) - road type - * - p2 = (bit 10) - set road direction - * - p2 = (bit 11) - defines two different behaviors for this command: - * - 0 = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile - * - 1 = Fail if an obstacle is found. Always take into account bit 0 and 1. This behavior is used for scripts - * @param text unused + * @param end_tile end tile of drag + * @param rt road type + * @param axis direction + * @param drd set road direction + * @param start_half start tile starts in the 2nd half of tile (p2 & 1). Only used if \c is_ai is set or if we are building a single tile + * @param end_half end tile starts in the 2nd half of tile (p2 & 2). Only used if \c is_ai is set or if we are building a single tile + * @param is_ai defines two different behaviors for this command: + * - false = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile + * - true = Fail if an obstacle is found. Always take into account start_half and end_half. This behavior is used for scripts * @return the cost of this operation or an error */ -CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai) { - DisallowedRoadDirections drd = DRD_NORTHBOUND; + if (end_tile >= MapSize()) return CMD_ERROR; - if (p1 >= MapSize()) return CMD_ERROR; - TileIndex end_tile = p1; + if (!ValParamRoadType(rt) || !IsEnumValid(axis) || !IsEnumValid(drd)) return CMD_ERROR; - RoadType rt = Extract(p2); - if (!ValParamRoadType(rt)) return CMD_ERROR; - - Axis axis = Extract(p2); /* Only drag in X or Y direction dictated by the direction variable */ if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis DiagDirection dir = AxisToDiagDir(axis); - /* Swap direction, also the half-tile drag var (bit 0 and 1) */ - if (start_tile > end_tile || (start_tile == end_tile && HasBit(p2, 0))) { + /* Swap direction, also the half-tile drag vars. */ + if (start_tile > end_tile || (start_tile == end_tile && start_half)) { dir = ReverseDiagDir(dir); - p2 ^= 3; - drd = DRD_SOUTHBOUND; + std::swap(start_half, end_half); + if (drd == DRD_NORTHBOUND || drd == DRD_SOUTHBOUND) drd ^= DRD_BOTH; } /* On the X-axis, we have to swap the initial bits, so they * will be interpreted correctly in the GTTS. Furthermore * when you just 'click' on one tile to build them. */ - if ((axis == AXIS_Y) == (start_tile == end_tile && HasBit(p2, 0) == HasBit(p2, 1))) drd ^= DRD_BOTH; - /* No disallowed direction bits have to be toggled */ - if (!HasBit(p2, 10)) drd = DRD_NONE; + if ((drd == DRD_NORTHBOUND || drd == DRD_SOUTHBOUND) && (axis == AXIS_Y) == (start_tile == end_tile && start_half == end_half)) drd ^= DRD_BOTH; CommandCost cost(EXPENSES_CONSTRUCTION); CommandCost last_error = CMD_ERROR; @@ -1021,7 +1005,6 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p bool had_bridge = false; bool had_tunnel = false; bool had_success = false; - bool is_ai = HasBit(p2, 11); /* Start tile is the first tile clicked by the user. */ for (;;) { @@ -1037,11 +1020,11 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p } } else { /* Road parts only have to be built at the start tile or at the end tile. */ - if (tile == end_tile && !HasBit(p2, 1)) bits &= DiagDirToRoadBits(ReverseDiagDir(dir)); - if (tile == start_tile && HasBit(p2, 0)) bits &= DiagDirToRoadBits(dir); + if (tile == end_tile && !end_half) bits &= DiagDirToRoadBits(ReverseDiagDir(dir)); + if (tile == start_tile && start_half) bits &= DiagDirToRoadBits(dir); } - CommandCost ret = Command::Do(flags, tile, drd << 11 | rt << 4 | bits, 0, {}); + CommandCost ret = Command::Do(flags, tile, bits, rt, drd, 0); if (ret.Failed()) { last_error = ret; if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) { @@ -1080,36 +1063,28 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p * Remove a long piece of road. * @param flags operation to perform * @param start_tile start tile of drag - * @param p1 end tile of drag - * @param p2 various bitstuffed elements - * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) - * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) - * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) - * - p2 = (bit 3 - 8) - road type - * @param text unused + * @param end_tile end tile of drag + * @param rt road type + * @param axis direction + * @param start_half start tile starts in the 2nd half of tile + * @param end_half end tile starts in the 2nd half of tile (p2 & 2) * @return the cost of this operation or an error */ -CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, bool start_half, bool end_half) { CommandCost cost(EXPENSES_CONSTRUCTION); - if (p1 >= MapSize()) return CMD_ERROR; + if (end_tile >= MapSize()) return CMD_ERROR; + if (!ValParamRoadType(rt) || !IsEnumValid(axis)) return CMD_ERROR; - TileIndex end_tile = p1; - RoadType rt = Extract(p2); - if (!ValParamRoadType(rt)) return CMD_ERROR; - - Axis axis = Extract(p2); /* Only drag in X or Y direction dictated by the direction variable */ if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis - /* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */ - if (start_tile > end_tile || (start_tile == end_tile && HasBit(p2, 0))) { - TileIndex t = start_tile; - start_tile = end_tile; - end_tile = t; - p2 ^= IsInsideMM(p2 & 3, 1, 3) ? 3 : 0; + /* Swap start and ending tile, also the half-tile drag vars. */ + if (start_tile > end_tile || (start_tile == end_tile && start_half)) { + std::swap(start_tile, end_tile); + std::swap(start_half, end_half); } Money money_available = GetAvailableMoneyForCommand(); @@ -1121,8 +1096,8 @@ CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 for (;;) { RoadBits bits = AxisToRoadBits(axis); - if (tile == end_tile && !HasBit(p2, 1)) bits &= ROAD_NW | ROAD_NE; - if (tile == start_tile && HasBit(p2, 0)) bits &= ROAD_SE | ROAD_SW; + if (tile == end_tile && !end_half) bits &= ROAD_NW | ROAD_NE; + if (tile == start_tile && start_half) bits &= ROAD_SE | ROAD_SW; /* try to remove the halves. */ if (bits != 0) { @@ -1132,7 +1107,7 @@ CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, uint32 if (flags & DC_EXEC) { money_spent += ret.GetCost(); if (money_spent > 0 && money_spent > money_available) { - _additional_cash_required = Command::Do(flags & ~DC_EXEC, start_tile, end_tile, p2, {}).GetCost(); + _additional_cash_required = Command::Do(flags & ~DC_EXEC, start_tile, end_tile, rt, axis, start_half, end_half).GetCost(); return cost; } RemoveRoad(tile, flags, bits, rtt, true, false); @@ -2342,17 +2317,12 @@ static void ConvertRoadTypeOwner(TileIndex tile, uint num_pieces, Owner owner, R * * @param flags operation to perform * @param tile end tile of road conversion drag - * @param p1 start tile of drag - * @param p2 various bitstuffed elements: - * - p2 = (bit 0..5) new roadtype to convert to. - * @param text unused + * @param area_start start tile of drag + * @param to_type new roadtype to convert to. * @return the cost of this operation or an error */ -CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_start, RoadType to_type) { - RoadType to_type = Extract(p2); - - TileIndex area_start = p1; TileIndex area_end = tile; if (!ValParamRoadType(to_type)) return CMD_ERROR; diff --git a/src/road_cmd.h b/src/road_cmd.h index 0cab1252f0..3c142bdfed 100644 --- a/src/road_cmd.h +++ b/src/road_cmd.h @@ -17,11 +17,11 @@ void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt); void UpdateNearestTownForRoadTiles(bool invalidate); -CommandProc CmdBuildLongRoad; -CommandProc CmdRemoveLongRoad; -CommandProc CmdBuildRoad; +CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai); +CommandCost CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, bool start_half, bool end_half); +CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, RoadType rt, DisallowedRoadDirections toggle_drd, TownID town_id); CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, RoadType rt, DiagDirection dir); -CommandProc CmdConvertRoad; +CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_start, RoadType to_type); DEF_CMD_TRAIT(CMD_BUILD_LONG_ROAD, CmdBuildLongRoad, CMD_AUTO | CMD_NO_WATER | CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_REMOVE_LONG_ROAD, CmdRemoveLongRoad, CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // towns may disallow removing road bits (as they are connected) in test, but in exec they're removed and thus removing is allowed. diff --git a/src/road_gui.cpp b/src/road_gui.cpp index beba949e4c..1aa0b59ac4 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -47,22 +47,10 @@ static void ShowRoadDepotPicker(Window *parent); static bool _remove_button_clicked; static bool _one_way_button_clicked; -/** - * Define the values of the RoadFlags - * @see CmdBuildLongRoad - */ -enum RoadFlags { - RF_NONE = 0x00, - RF_START_HALFROAD_Y = 0x01, // The start tile in Y-dir should have only a half road - RF_END_HALFROAD_Y = 0x02, // The end tile in Y-dir should have only a half road - RF_DIR_Y = 0x04, // The direction is Y-dir - RF_DIR_X = RF_NONE, // Dummy; Dir X is set when RF_DIR_Y is not set - RF_START_HALFROAD_X = 0x08, // The start tile in X-dir should have only a half road - RF_END_HALFROAD_X = 0x10, // The end tile in X-dir should have only a half road -}; -DECLARE_ENUM_AS_BIT_SET(RoadFlags) - -static RoadFlags _place_road_flag; +static Axis _place_road_dir; +static bool _place_road_start_half_x; +static bool _place_road_start_half_y; +static bool _place_road_end_half; static RoadType _cur_roadtype; @@ -124,7 +112,7 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) /* if there is a roadpiece just outside of the station entrance, build a connecting route */ if (IsNormalRoadTile(tile)) { if (GetRoadBits(tile, GetRoadTramType(_cur_roadtype)) != ROAD_NONE) { - Command::Post(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, {}); + Command::Post(tile, DiagDirToRoadBits(ReverseDiagDir(direction)), _cur_roadtype, DRD_NONE, 0); } } } @@ -523,21 +511,21 @@ struct BuildRoadToolbarWindow : Window { _one_way_button_clicked = RoadTypeIsRoad(this->roadtype) ? this->IsWidgetLowered(WID_ROT_ONE_WAY) : false; switch (this->last_started_action) { case WID_ROT_ROAD_X: - _place_road_flag = RF_DIR_X; - if (_tile_fract_coords.x >= 8) _place_road_flag |= RF_START_HALFROAD_X; + _place_road_dir = AXIS_X; + _place_road_start_half_x = _tile_fract_coords.x >= 8; VpStartPlaceSizing(tile, VPM_FIX_Y, DDSP_PLACE_ROAD_X_DIR); break; case WID_ROT_ROAD_Y: - _place_road_flag = RF_DIR_Y; - if (_tile_fract_coords.y >= 8) _place_road_flag |= RF_START_HALFROAD_Y; + _place_road_dir = AXIS_Y; + _place_road_start_half_y = _tile_fract_coords.y >= 8; VpStartPlaceSizing(tile, VPM_FIX_X, DDSP_PLACE_ROAD_Y_DIR); break; case WID_ROT_AUTOROAD: - _place_road_flag = RF_NONE; - if (_tile_fract_coords.x >= 8) _place_road_flag |= RF_START_HALFROAD_X; - if (_tile_fract_coords.y >= 8) _place_road_flag |= RF_START_HALFROAD_Y; + _place_road_dir = INVALID_AXIS; + _place_road_start_half_x = _tile_fract_coords.x >= 8; + _place_road_start_half_y = _tile_fract_coords.y >= 8; VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_PLACE_AUTOROAD); break; @@ -564,7 +552,7 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_BUILD_TUNNEL: Command::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRoadTunnel, - tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, {}); + tile, TRANSPORT_ROAD, _cur_roadtype); break; case WID_ROT_CONVERT_ROAD: @@ -603,30 +591,26 @@ struct BuildRoadToolbarWindow : Window { * bits and if needed we set them again. */ switch (select_proc) { case DDSP_PLACE_ROAD_X_DIR: - _place_road_flag &= ~RF_END_HALFROAD_X; - if (pt.x & 8) _place_road_flag |= RF_END_HALFROAD_X; + _place_road_end_half = pt.x & 8; break; case DDSP_PLACE_ROAD_Y_DIR: - _place_road_flag &= ~RF_END_HALFROAD_Y; - if (pt.y & 8) _place_road_flag |= RF_END_HALFROAD_Y; + _place_road_end_half = pt.y & 8; break; case DDSP_PLACE_AUTOROAD: - _place_road_flag &= ~(RF_END_HALFROAD_Y | RF_END_HALFROAD_X); - if (pt.y & 8) _place_road_flag |= RF_END_HALFROAD_Y; - if (pt.x & 8) _place_road_flag |= RF_END_HALFROAD_X; - /* For autoroad we need to update the * direction of the road */ if (_thd.size.x > _thd.size.y || (_thd.size.x == _thd.size.y && ( (_tile_fract_coords.x < _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) < 16) || (_tile_fract_coords.x > _tile_fract_coords.y && (_tile_fract_coords.x + _tile_fract_coords.y) > 16) ))) { /* Set dir = X */ - _place_road_flag &= ~RF_DIR_Y; + _place_road_dir = AXIS_X; + _place_road_end_half = pt.x & 8; } else { /* Set dir = Y */ - _place_road_flag |= RF_DIR_Y; + _place_road_dir = AXIS_Y; + _place_road_end_half = pt.y & 8; } break; @@ -654,25 +638,18 @@ struct BuildRoadToolbarWindow : Window { case DDSP_PLACE_ROAD_X_DIR: case DDSP_PLACE_ROAD_Y_DIR: - case DDSP_PLACE_AUTOROAD: - /* Flag description: - * Use the first three bits (0x07) if dir == Y - * else use the last 2 bits (X dir has - * not the 3rd bit set) */ - - /* Even if _cur_roadtype_id is a uint8 we only use 5 bits so - * we could ignore the last 3 bits and reuse them for other - * flags */ - _place_road_flag = (RoadFlags)((_place_road_flag & RF_DIR_Y) ? (_place_road_flag & 0x07) : (_place_road_flag >> 3)); + case DDSP_PLACE_AUTOROAD: { + bool start_half = _place_road_dir == AXIS_Y ? _place_road_start_half_y : _place_road_start_half_y; if (_remove_button_clicked) { Command::Post(this->rti->strings.err_remove_road, CcPlaySound_CONSTRUCTION_OTHER, - start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10), {}); + start_tile, end_tile, _cur_roadtype, _place_road_dir, start_half, _place_road_end_half); } else { Command::Post(this->rti->strings.err_build_road, CcPlaySound_CONSTRUCTION_OTHER, - start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10), {}); + start_tile, end_tile, _cur_roadtype, _place_road_dir, _one_way_button_clicked ? DRD_NORTHBOUND : DRD_NONE, start_tile, _place_road_end_half, false); } break; + } case DDSP_BUILD_BUSSTOP: case DDSP_REMOVE_BUSSTOP: @@ -699,7 +676,7 @@ struct BuildRoadToolbarWindow : Window { break; case DDSP_CONVERT_ROAD: - Command::Post(rti->strings.err_convert_road, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype, {}); + Command::Post(rti->strings.err_convert_road, CcPlaySound_CONSTRUCTION_OTHER, end_tile, start_tile, _cur_roadtype); break; } } @@ -707,7 +684,7 @@ struct BuildRoadToolbarWindow : Window { void OnPlacePresize(Point pt, TileIndex tile) override { - Command::Do(DC_AUTO, tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, {}); + Command::Do(DC_AUTO, tile, TRANSPORT_ROAD, _cur_roadtype); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); } diff --git a/src/road_map.h b/src/road_map.h index 22d0fa54d3..4cb9125ea6 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -15,6 +15,7 @@ #include "rail_type.h" #include "road_func.h" #include "tile_map.h" +#include "road_type.h" /** The different types of road tiles. */ @@ -281,18 +282,6 @@ static inline bool HasTownOwnedRoad(TileIndex t) return HasTileRoadType(t, RTT_ROAD) && IsRoadOwner(t, RTT_ROAD, OWNER_TOWN); } -/** Which directions are disallowed ? */ -enum DisallowedRoadDirections { - DRD_NONE, ///< None of the directions are disallowed - DRD_SOUTHBOUND, ///< All southbound traffic is disallowed - DRD_NORTHBOUND, ///< All northbound traffic is disallowed - DRD_BOTH, ///< All directions are disallowed - DRD_END, ///< Sentinel -}; -DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections) -/** Helper information for extract tool. */ -template <> struct EnumPropsT : MakeEnumPropsT {}; - /** * Gets the disallowed directions * @param t the tile to get the directions from diff --git a/src/road_type.h b/src/road_type.h index 969b141ba2..a792db7ba5 100644 --- a/src/road_type.h +++ b/src/road_type.h @@ -19,7 +19,7 @@ typedef uint32 RoadTypeLabel; * * @note currently only ROADTYPE_ROAD and ROADTYPE_TRAM are supported. */ -enum RoadType { +enum RoadType : byte { ROADTYPE_BEGIN = 0, ///< Used for iterations ROADTYPE_ROAD = 0, ///< Basic road type ROADTYPE_TRAM = 1, ///< Trams @@ -47,7 +47,7 @@ DECLARE_ENUM_AS_BIT_SET(RoadTypes) * This enumeration defines the possible road parts which * can be build on a tile. */ -enum RoadBits { +enum RoadBits : byte { ROAD_NONE = 0U, ///< No road-part is build ROAD_NW = 1U, ///< North-west part ROAD_SW = 2U, ///< South-west part @@ -68,4 +68,16 @@ enum RoadBits { DECLARE_ENUM_AS_BIT_SET(RoadBits) template <> struct EnumPropsT : MakeEnumPropsT {}; +/** Which directions are disallowed ? */ +enum DisallowedRoadDirections : byte { + DRD_NONE, ///< None of the directions are disallowed + DRD_SOUTHBOUND, ///< All southbound traffic is disallowed + DRD_NORTHBOUND, ///< All northbound traffic is disallowed + DRD_BOTH, ///< All directions are disallowed + DRD_END, ///< Sentinel +}; +DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections) +/** Helper information for extract tool. */ +template <> struct EnumPropsT : MakeEnumPropsT {}; + #endif /* ROAD_TYPE_H */ diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 0b8d9deff8..c1e510273a 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1131,7 +1131,7 @@ static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadType rt, RoadB /* The 'current' company is not necessarily the owner of the vehicle. */ Backup cur_company(_current_company, c, FILE_LINE); - CommandCost ret = Command::Do(DC_NO_WATER, t, rt << 4 | r, 0, {}); + CommandCost ret = Command::Do(DC_NO_WATER, t, r, rt, DRD_NONE, 0); cur_company.Restore(); return ret.Succeeded(); diff --git a/src/script/api/script_bridge.cpp b/src/script/api/script_bridge.cpp index dc357c2552..fbea9fb127 100644 --- a/src/script/api/script_bridge.cpp +++ b/src/script/api/script_bridge.cpp @@ -80,30 +80,17 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_ROAD || ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType())); EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD); - uint type = 0; switch (vehicle_type) { case ScriptVehicle::VT_ROAD: - type |= (TRANSPORT_ROAD << 15); - type |= (ScriptRoad::GetCurrentRoadType() << 8); - break; + ScriptObject::SetCallbackVariable(0, start); + ScriptObject::SetCallbackVariable(1, end); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildBridge1, end, start, TRANSPORT_ROAD, bridge_id, ScriptRoad::GetCurrentRoadType()); case ScriptVehicle::VT_RAIL: - type |= (TRANSPORT_RAIL << 15); - type |= (ScriptRail::GetCurrentRailType() << 8); - break; + return ScriptObject::Command::Do(end, start, TRANSPORT_RAIL, bridge_id, ScriptRail::GetCurrentRailType()); case ScriptVehicle::VT_WATER: - type |= (TRANSPORT_WATER << 15); - break; + return ScriptObject::Command::Do(end, start, TRANSPORT_WATER, bridge_id, 0); default: NOT_REACHED(); } - - /* For rail and water we do nothing special */ - if (vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER) { - return ScriptObject::Command::Do(end, start, type | bridge_id, {}); - } - - ScriptObject::SetCallbackVariable(0, start); - ScriptObject::SetCallbackVariable(1, end); - return ScriptObject::Command::Do(&::_DoCommandReturnBuildBridge1, end, start, type | bridge_id, {}); } /* static */ bool ScriptBridge::_BuildBridgeRoad1() @@ -115,7 +102,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::Command::Do(&::_DoCommandReturnBuildBridge2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptRoad::GetCurrentRoadType() << 4), 0, {}); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildBridge2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2), (::RoadType)ScriptRoad::GetCurrentRoadType(), DRD_NONE, 0); } /* static */ bool ScriptBridge::_BuildBridgeRoad2() @@ -127,7 +114,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::Command::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptRoad::GetCurrentRoadType() << 4), 0, {}); + return ScriptObject::Command::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1), (::RoadType)ScriptRoad::GetCurrentRoadType(), DRD_NONE, 0); } /* static */ bool ScriptBridge::RemoveBridge(TileIndex tile) diff --git a/src/script/api/script_marine.cpp b/src/script/api/script_marine.cpp index 8093233948..059157e276 100644 --- a/src/script/api/script_marine.cpp +++ b/src/script/api/script_marine.cpp @@ -108,7 +108,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ bool ScriptMarine::BuildCanal(TileIndex tile) @@ -116,7 +116,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, tile, WATER_CLASS_CANAL, {}); + return ScriptObject::Command::Do(tile, tile, WATER_CLASS_CANAL, false); } /* static */ bool ScriptMarine::RemoveWaterDepot(TileIndex tile) diff --git a/src/script/api/script_road.cpp b/src/script/api/script_road.cpp index c629396b70..297a8f56c1 100644 --- a/src/script/api/script_road.cpp +++ b/src/script/api/script_road.cpp @@ -129,7 +129,7 @@ EnforcePrecondition(false, ::IsValidTile(end_tile)); EnforcePrecondition(false, IsRoadTypeAvailable(road_type)); - return ScriptObject::Command::Do(start_tile, end_tile, (::RoadType)road_type, {}); + return ScriptObject::Command::Do(start_tile, end_tile, (::RoadType)road_type); } /* Helper functions for ScriptRoad::CanBuildConnectedRoadParts(). */ @@ -495,7 +495,8 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, !one_way || RoadTypeIsRoad(ScriptObject::GetRoadType())); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - return ScriptObject::Command::Do(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (((start < end) == !full) ? 1 : 2) | (ScriptObject::GetRoadType() << 3) | ((one_way ? 1 : 0) << 10) | 1 << 11, {}); + Axis axis = ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X; + return ScriptObject::Command::Do(start, end, ScriptObject::GetRoadType(), axis, one_way ? DRD_NORTHBOUND : DRD_NONE, (start < end) == !full, (start < end) != !full, true); } /* static */ bool ScriptRoad::BuildRoad(TileIndex start, TileIndex end) @@ -570,7 +571,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end)); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - return ScriptObject::Command::Do(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 1 : 2) | (ScriptObject::GetRoadType() << 3), {}); + return ScriptObject::Command::Do(start, end, ScriptObject::GetRoadType(), ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X, start < end, start >= end); } /* static */ bool ScriptRoad::RemoveRoadFull(TileIndex start, TileIndex end) @@ -582,7 +583,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end)); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - return ScriptObject::Command::Do(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 2 : 1) | (ScriptObject::GetRoadType() << 3), {}); + return ScriptObject::Command::Do(start, end, ScriptObject::GetRoadType(), ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X, start >= end, start < end); } /* static */ bool ScriptRoad::RemoveRoadDepot(TileIndex tile) diff --git a/src/script/api/script_tunnel.cpp b/src/script/api/script_tunnel.cpp index ea9cbc5186..8529f908db 100644 --- a/src/script/api/script_tunnel.cpp +++ b/src/script/api/script_tunnel.cpp @@ -88,22 +88,13 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_ROAD || ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType())); EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD); - uint type = 0; - if (vehicle_type == ScriptVehicle::VT_ROAD) { - type |= (TRANSPORT_ROAD << 8); - type |= ScriptRoad::GetCurrentRoadType(); - } else { - type |= (TRANSPORT_RAIL << 8); - type |= ScriptRail::GetCurrentRailType(); - } - - /* For rail we do nothing special */ if (vehicle_type == ScriptVehicle::VT_RAIL) { - return ScriptObject::Command::Do(start, type, 0, {}); + /* For rail we do nothing special */ + return ScriptObject::Command::Do(start, TRANSPORT_RAIL, ScriptRail::GetCurrentRailType()); + } else { + ScriptObject::SetCallbackVariable(0, start); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildTunnel1, start, TRANSPORT_ROAD, ScriptRoad::GetCurrentRoadType()); } - - ScriptObject::SetCallbackVariable(0, start); - return ScriptObject::Command::Do(&::_DoCommandReturnBuildTunnel1, start, type, 0, {}); } /* static */ bool ScriptTunnel::_BuildTunnelRoad1() @@ -115,7 +106,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::Command::Do(&::_DoCommandReturnBuildTunnel2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptObject::GetRoadType() << 4), 0, {}); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildTunnel2, start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2), ScriptRoad::GetRoadType(), DRD_NONE, 0); } /* static */ bool ScriptTunnel::_BuildTunnelRoad2() @@ -127,7 +118,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::Command::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptObject::GetRoadType() << 4), 0, {}); + return ScriptObject::Command::Do(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1), ScriptRoad::GetRoadType(), DRD_NONE, 0); } /* static */ bool ScriptTunnel::RemoveTunnel(TileIndex tile) diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 8e87739d3d..7a564d48ab 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -943,7 +943,7 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) * If that fails clear the land, and if that fails exit. * This is to make sure that we can build a road here later. */ RoadType rt = GetTownRoadType(t); - if (Command::Do(DC_AUTO | DC_NO_WATER, tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X) | (rt << 4), 0, {}).Failed() && + if (Command::Do(DC_AUTO | DC_NO_WATER, tile, (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X, rt, DRD_NONE, 0).Failed() && Command::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Failed()) { return false; } @@ -1112,7 +1112,7 @@ static bool GrowTownWithExtraHouse(Town *t, TileIndex tile) static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd) { RoadType rt = GetTownRoadType(t); - if (Command::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile, rcmd | (rt << 4), t->index, {}).Succeeded()) { + if (Command::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile, rcmd, rt, DRD_NONE, t->index).Succeeded()) { _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1159,7 +1159,7 @@ static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, con if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false; /* If a road tile can be built, the construction is allowed. */ - return Command::Do(DC_AUTO | DC_NO_WATER, next_tile, rcmd | (rt << 4), t->index, {}).Succeeded(); + return Command::Do(DC_AUTO | DC_NO_WATER, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded(); } /** @@ -1227,8 +1227,8 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi /* Can we actually build the bridge? */ RoadType rt = GetTownRoadType(t); - if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, {}).Succeeded()) { - Command::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags()), tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, {}); + if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) { + Command::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt); _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1298,8 +1298,8 @@ static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDi /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */ RoadType rt = GetTownRoadType(t); - if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, rt | (TRANSPORT_ROAD << 8), 0, {}).Succeeded()) { - Command::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags()), tile, rt | (TRANSPORT_ROAD << 8), 0, {}); + if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, TRANSPORT_ROAD, rt).Succeeded()) { + Command::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags()), tile, TRANSPORT_ROAD, rt); _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1739,7 +1739,7 @@ static bool GrowTown(Town *t) if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) { if (Command::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Succeeded()) { RoadType rt = GetTownRoadType(t); - Command::Do(DC_EXEC | DC_AUTO, tile, GenRandomRoadBits() | (rt << 4), t->index, {}); + Command::Do(DC_EXEC | DC_AUTO, tile, GenRandomRoadBits(), rt, DRD_NONE, t->index); cur_company.Restore(); return true; } diff --git a/src/transport_type.h b/src/transport_type.h index b244e48b31..172649aba5 100644 --- a/src/transport_type.h +++ b/src/transport_type.h @@ -16,7 +16,7 @@ typedef uint16 UnitID; /** Available types of transport */ -enum TransportType { +enum TransportType : byte { /* These constants are for now linked to the representation of bridges * and tunnels, so they can be used by GetTileTrackStatus_TunnelBridge. * In an ideal world, these constants would be used everywhere when diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 85c611ae5d..14ff79854d 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -251,38 +251,31 @@ static Money TunnelBridgeClearCost(TileIndex tile, Price base_price) /** * Build a Bridge * @param flags type of operation - * @param end_tile end tile - * @param p1 packed start tile coords (~ dx) - * @param p2 various bitstuffed elements - * - p2 = (bit 0- 7) - bridge type (hi bh) - * - p2 = (bit 8-13) - rail type or road types. - * - p2 = (bit 15-16) - transport type. - * @param text unused + * @param tile_end end tile + * @param tile_start start tile + * @param transport_type transport type. + * @param bridge_type bridge type (hi bh) + * @param road_rail_type rail type or road types. * @return the cost of this operation or an error */ -CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, byte road_rail_type) { CompanyID company = _current_company; RailType railtype = INVALID_RAILTYPE; RoadType roadtype = INVALID_ROADTYPE; - /* unpack parameters */ - BridgeType bridge_type = GB(p2, 0, 8); - - if (!IsValidTile(p1)) return_cmd_error(STR_ERROR_BRIDGE_THROUGH_MAP_BORDER); - - TransportType transport_type = Extract(p2); + if (!IsValidTile(tile_start)) return_cmd_error(STR_ERROR_BRIDGE_THROUGH_MAP_BORDER); /* type of bridge */ switch (transport_type) { case TRANSPORT_ROAD: - roadtype = Extract(p2); + roadtype = (RoadType)road_rail_type; if (!ValParamRoadType(roadtype)) return CMD_ERROR; break; case TRANSPORT_RAIL: - railtype = Extract(p2); + railtype = (RailType)road_rail_type; if (!ValParamRailtype(railtype)) return CMD_ERROR; break; @@ -293,8 +286,6 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, u /* Airports don't have bridges. */ return CMD_ERROR; } - TileIndex tile_start = p1; - TileIndex tile_end = end_tile; if (company == OWNER_DEITY) { if (transport_type != TRANSPORT_ROAD) return CMD_ERROR; @@ -627,28 +618,25 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex end_tile, uint32 p1, u * Build Tunnel. * @param flags type of operation * @param start_tile start tile of tunnel - * @param p1 bit 0-5 railtype or roadtype - * bit 8-9 transport type - * @param p2 unused - * @param text unused + * @param transport_type transport type + * @param road_rail_type railtype or roadtype * @return the cost of this operation or an error */ -CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportType transport_type, byte road_rail_type) { CompanyID company = _current_company; - TransportType transport_type = Extract(p1); RailType railtype = INVALID_RAILTYPE; RoadType roadtype = INVALID_ROADTYPE; _build_tunnel_endtile = 0; switch (transport_type) { case TRANSPORT_RAIL: - railtype = Extract(p1); + railtype = (RailType)road_rail_type; if (!ValParamRailtype(railtype)) return CMD_ERROR; break; case TRANSPORT_ROAD: - roadtype = Extract(p1); + roadtype = (RoadType)road_rail_type; if (!ValParamRoadType(roadtype)) return CMD_ERROR; break; diff --git a/src/tunnelbridge_cmd.h b/src/tunnelbridge_cmd.h index 6c78db48b1..ae924cf69d 100644 --- a/src/tunnelbridge_cmd.h +++ b/src/tunnelbridge_cmd.h @@ -11,9 +11,11 @@ #define TUNNELBRIDGE_CMD_H #include "command_type.h" +#include "transport_type.h" +#include "bridge.h" -CommandProc CmdBuildBridge; -CommandProc CmdBuildTunnel; +CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, byte road_rail_type); +CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportType transport_type, byte road_rail_type); DEF_CMD_TRAIT(CMD_BUILD_BRIDGE, CmdBuildBridge, CMD_DEITY | CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_BUILD_TUNNEL, CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 3c96f79ad8..ee911312ef 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -411,12 +411,9 @@ static CommandCost RemoveLock(TileIndex tile, DoCommandFlag flags) * Builds a lock. * @param flags type of operation * @param tile tile where to place the lock - * @param p1 unused - * @param p2 unused - * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile) { DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); if (dir == INVALID_DIAGDIR) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); @@ -435,34 +432,31 @@ bool RiverModifyDesertZone(TileIndex tile, void *) * Build a piece of canal. * @param flags type of operation * @param tile end tile of stretch-dragging - * @param p1 start tile of stretch-dragging - * @param p2 various bitstuffed data - * bits 0-1: waterclass to build. sea and river can only be built in scenario editor - * bit 2: Whether to use the Orthogonal (0) or Diagonal (1) iterator. - * @param text unused + * @param start_tile start tile of stretch-dragging + * @param wc waterclass to build. sea and river can only be built in scenario editor + * @param diagonal Whether to use the Orthogonal (0) or Diagonal (1) iterator. * @return the cost of this operation or an error */ -CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal) { - WaterClass wc = Extract(p2); - if (p1 >= MapSize() || wc == WATER_CLASS_INVALID) return CMD_ERROR; + if (start_tile >= MapSize() || !IsEnumValid(wc)) return CMD_ERROR; /* Outside of the editor you can only build canals, not oceans */ if (wc != WATER_CLASS_CANAL && _game_mode != GM_EDITOR) return CMD_ERROR; /* Outside the editor you can only drag canals, and not areas */ if (_game_mode != GM_EDITOR) { - TileArea ta(tile, (TileIndex)p1); + TileArea ta(tile, start_tile); if (ta.w != 1 && ta.h != 1) return CMD_ERROR; } CommandCost cost(EXPENSES_CONSTRUCTION); std::unique_ptr iter; - if (HasBit(p2, 2)) { - iter = std::make_unique(tile, (TileIndex)p1); + if (diagonal) { + iter = std::make_unique(tile, start_tile); } else { - iter = std::make_unique(tile, (TileIndex)p1); + iter = std::make_unique(tile, start_tile); } for (; *iter != INVALID_TILE; ++(*iter)) { diff --git a/src/water_cmd.h b/src/water_cmd.h index 4d3375aa39..1c56790327 100644 --- a/src/water_cmd.h +++ b/src/water_cmd.h @@ -11,10 +11,11 @@ #define WATER_CMD_H #include "command_type.h" +#include "water_map.h" CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis); -CommandProc CmdBuildCanal; -CommandProc CmdBuildLock; +CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal); +CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile); DEF_CMD_TRAIT(CMD_BUILD_SHIP_DEPOT, CmdBuildShipDepot, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_BUILD_CANAL, CmdBuildCanal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/water_map.h b/src/water_map.h index 22e54e967f..793d07c8a2 100644 --- a/src/water_map.h +++ b/src/water_map.h @@ -44,7 +44,7 @@ enum WaterTileType { }; /** classes of water (for #WATER_TILE_CLEAR water tile type). */ -enum WaterClass { +enum WaterClass : byte { WATER_CLASS_SEA, ///< Sea. WATER_CLASS_CANAL, ///< Canal. WATER_CLASS_RIVER, ///< River. From e08b3abe7ff65c193781a74c170f45b2f1dcf0a5 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Wed, 17 Nov 2021 00:40:06 +0100 Subject: [PATCH 28/60] Codechange: Un-bitstuff group and autoreplace commands. --- src/autoreplace_cmd.cpp | 30 +++----- src/autoreplace_cmd.h | 7 +- src/autoreplace_gui.cpp | 8 +- src/company_gui.cpp | 2 +- src/gfx_type.h | 2 +- src/group_cmd.cpp | 129 ++++++++++++-------------------- src/group_cmd.h | 27 +++++-- src/group_gui.cpp | 32 ++++---- src/order_backup.cpp | 2 +- src/script/api/script_group.cpp | 20 ++--- src/vehicle.cpp | 2 +- src/vehicle_cmd.cpp | 4 +- 12 files changed, 118 insertions(+), 147 deletions(-) diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 8338172b02..f2ef317f04 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -405,7 +405,7 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command::Do(DC_EXEC, CO_SHARE, new_head->index, old_head->index)); /* Copy group membership */ - if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command::Do(DC_EXEC, 0, old_head->group_id, new_head->index, {})); + if (cost.Succeeded() && old_head != new_head) cost.AddCost(Command::Do(DC_EXEC, old_head->group_id, new_head->index, false)); /* Perform start/stop check whether the new vehicle suits newgrf restrictions etc. */ if (cost.Succeeded()) { @@ -713,15 +713,12 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon * Autoreplaces a vehicle * Trains are replaced as a whole chain, free wagons in depot are replaced on their own * @param flags type of operation - * @param tile not used - * @param p1 Index of vehicle - * @param p2 not used - * @param text unused + * @param veh_id Index of vehicle * @return the cost of this operation or an error */ -CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, VehicleID veh_id) { - Vehicle *v = Vehicle::GetIfValid(p1); + Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); @@ -802,24 +799,17 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, TileIndex tile, uint32 p1 /** * Change engine renewal parameters * @param flags operation to perform - * @param tile unused - * @param p1 packed data - * - bit 0 = replace when engine gets old? - * - bits 16-31 = engine group - * @param p2 packed data - * - bits 0-15 = old engine type - * - bits 16-31 = new engine type - * @param text unused + * @param id_g engine group + * @param old_engine_type old engine type + * @param new_engine_type new engine type + * @param when_old replace when engine gets old? * @return the cost of this operation or an error */ -CommandCost CmdSetAutoReplace(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetAutoReplace(DoCommandFlag flags, GroupID id_g, EngineID old_engine_type, EngineID new_engine_type, bool when_old) { Company *c = Company::GetIfValid(_current_company); if (c == nullptr) return CMD_ERROR; - EngineID old_engine_type = GB(p2, 0, 16); - EngineID new_engine_type = GB(p2, 16, 16); - GroupID id_g = GB(p1, 16, 16); CommandCost cost; if (Group::IsValidID(id_g) ? Group::Get(id_g)->owner != _current_company : !IsAllGroupID(id_g) && !IsDefaultGroupID(id_g)) return CMD_ERROR; @@ -829,7 +819,7 @@ CommandCost CmdSetAutoReplace(DoCommandFlag flags, TileIndex tile, uint32 p1, ui if (!Engine::IsValidID(new_engine_type)) return CMD_ERROR; if (!CheckAutoreplaceValidity(old_engine_type, new_engine_type, _current_company)) return CMD_ERROR; - cost = AddEngineReplacementForCompany(c, old_engine_type, new_engine_type, id_g, HasBit(p1, 0), flags); + cost = AddEngineReplacementForCompany(c, old_engine_type, new_engine_type, id_g, when_old, flags); } else { cost = RemoveEngineReplacementForCompany(c, old_engine_type, id_g, flags); } diff --git a/src/autoreplace_cmd.h b/src/autoreplace_cmd.h index 14088d6dc5..c42e740c93 100644 --- a/src/autoreplace_cmd.h +++ b/src/autoreplace_cmd.h @@ -11,9 +11,12 @@ #define AUTOREPLACE_CMD_H #include "command_type.h" +#include "vehicle_type.h" +#include "engine_type.h" +#include "group_type.h" -CommandProc CmdAutoreplaceVehicle; -CommandProc CmdSetAutoReplace; +CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, VehicleID veh_id); +CommandCost CmdSetAutoReplace(DoCommandFlag flags, GroupID id_g, EngineID old_engine_type, EngineID new_engine_type, bool when_old); DEF_CMD_TRAIT(CMD_AUTOREPLACE_VEHICLE, CmdAutoreplaceVehicle, 0, CMDT_VEHICLE_MANAGEMENT) DEF_CMD_TRAIT(CMD_SET_AUTOREPLACE, CmdSetAutoReplace, 0, CMDT_VEHICLE_MANAGEMENT) diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index c5cfd04cb6..00eba4044b 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -220,7 +220,7 @@ class ReplaceVehicleWindow : public Window { { EngineID veh_from = this->sel_engine[0]; EngineID veh_to = this->sel_engine[1]; - Command::Post(0, (replace_when_old ? 1 : 0) | (this->sel_group << 16), veh_from + (veh_to << 16), {}); + Command::Post(this->sel_group, veh_from, veh_to, replace_when_old); } public: @@ -544,7 +544,7 @@ public: case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: { const Group *g = Group::GetIfValid(this->sel_group); if (g != nullptr) { - Command::Post(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), {}); + Command::Post(this->sel_group, GroupFlags::GF_REPLACE_WAGON_REMOVAL, !HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL), _ctrl_pressed); } else { // toggle renew_keep_length Command::Post(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, "company.renew_keep_length"); @@ -565,7 +565,7 @@ public: case WID_RV_STOP_REPLACE: { // Stop replacing EngineID veh_from = this->sel_engine[0]; - Command::Post(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), {}); + Command::Post(this->sel_group, veh_from, INVALID_ENGINE, false); break; } @@ -587,7 +587,7 @@ public: if (click_side == 0 && _ctrl_pressed && e != INVALID_ENGINE && (GetGroupNumEngines(_local_company, sel_group, e) == 0 || GetGroupNumEngines(_local_company, ALL_GROUP, e) == 0)) { EngineID veh_from = e; - Command::Post(0, this->sel_group << 16, veh_from + (INVALID_ENGINE << 16), {}); + Command::Post(this->sel_group, veh_from, INVALID_ENGINE, false); break; } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index c2695b9105..cefab6d127 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1005,7 +1005,7 @@ public: } } else { /* Setting group livery */ - Command::Post(0, this->sel, (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256) | (index << 16), {}); + Command::Post(this->sel, widget == WID_SCL_PRI_COL_DROPDOWN, (Colours)index); } } diff --git a/src/gfx_type.h b/src/gfx_type.h index a6bf3cf6d5..932a6cb87d 100644 --- a/src/gfx_type.h +++ b/src/gfx_type.h @@ -223,7 +223,7 @@ struct SubSprite { int left, top, right, bottom; }; -enum Colours { +enum Colours : byte { COLOUR_BEGIN, COLOUR_DARK_BLUE = COLOUR_BEGIN, COLOUR_PALE_GREEN, diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index 2ff8a09dfd..4b34ad382a 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -295,20 +295,17 @@ Group::Group(Owner owner) /** * Create a new vehicle group. * @param flags type of operation - * @param tile unused - * @param p1 vehicle type - * @param p2 parent groupid - * @param text unused + * @param vt vehicle type + * @param parent_group parent groupid * @return the cost of this operation or an error */ -CommandCost CmdCreateGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateGroup(DoCommandFlag flags, VehicleType vt, GroupID parent_group) { - VehicleType vt = Extract(p1); if (!IsCompanyBuildableVehicleType(vt)) return CMD_ERROR; if (!Group::CanAllocateItem()) return CMD_ERROR; - const Group *pg = Group::GetIfValid(GB(p2, 0, 16)); + const Group *pg = Group::GetIfValid(parent_group); if (pg != nullptr) { if (pg->owner != _current_company) return CMD_ERROR; if (pg->vehicle_type != vt) return CMD_ERROR; @@ -344,25 +341,21 @@ CommandCost CmdCreateGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 /** * Add all vehicles in the given group to the default group and then deletes the group. * @param flags type of operation - * @param tile unused - * @param p1 index of array group - * - p1 bit 0-15 : GroupID - * @param p2 unused - * @param text unused + * @param group_id index of group * @return the cost of this operation or an error */ -CommandCost CmdDeleteGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDeleteGroup(DoCommandFlag flags, GroupID group_id) { - Group *g = Group::GetIfValid(p1); + Group *g = Group::GetIfValid(group_id); if (g == nullptr || g->owner != _current_company) return CMD_ERROR; /* Remove all vehicles from the group */ - Command::Do(flags, 0, p1, 0, {}); + Command::Do(flags, group_id); /* Delete sub-groups */ for (const Group *gp : Group::Iterate()) { if (gp->parent == g->index) { - Command::Do(flags, 0, gp->index, 0, {}); + Command::Do(flags, gp->index); } } @@ -396,21 +389,18 @@ CommandCost CmdDeleteGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 /** * Alter a group * @param flags type of operation - * @param tile unused - * @param p1 index of array group - * - p1 bit 0-15 : GroupID - * - p1 bit 16: 0 - Rename grouop - * 1 - Set group parent - * @param p2 parent group index + * @param mode Operation to perform. + * @param group_id GroupID + * @param parent_id parent group index * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdAlterGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAlterGroup(DoCommandFlag flags, AlterGroupMode mode, GroupID group_id, GroupID parent_id, const std::string &text) { - Group *g = Group::GetIfValid(GB(p1, 0, 16)); + Group *g = Group::GetIfValid(group_id); if (g == nullptr || g->owner != _current_company) return CMD_ERROR; - if (!HasBit(p1, 16)) { + if (mode == AlterGroupMode::Rename) { /* Rename group */ bool reset = text.empty(); @@ -426,9 +416,9 @@ CommandCost CmdAlterGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 g->name = text; } } - } else { + } else if (mode == AlterGroupMode::SetParent) { /* Set group parent */ - const Group *pg = Group::GetIfValid(GB(p2, 0, 16)); + const Group *pg = Group::GetIfValid(parent_id); if (pg != nullptr) { if (pg->owner != _current_company) return CMD_ERROR; @@ -452,6 +442,8 @@ CommandCost CmdAlterGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 MarkWholeScreenDirty(); } } + } else { + return CMD_ERROR; } if (flags & DC_EXEC) { @@ -500,19 +492,15 @@ static void AddVehicleToGroup(Vehicle *v, GroupID new_g) /** * Add a vehicle to a group * @param flags type of operation - * @param tile unused - * @param p1 index of array group - * - p1 bit 0-15 : GroupID - * @param p2 vehicle to add to a group - * - p2 bit 0-19 : VehicleID - * - p2 bit 31 : Add shared vehicles as well. - * @param text unused + * @param group_id index of group + * @param veh_id vehicle to add to a group + * @param add_shared Add shared vehicles as well. * @return the cost of this operation or an error */ -CommandCost CmdAddVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAddVehicleGroup(DoCommandFlag flags, GroupID group_id, VehicleID veh_id, bool add_shared) { - Vehicle *v = Vehicle::GetIfValid(GB(p2, 0, 20)); - GroupID new_g = p1; + Vehicle *v = Vehicle::GetIfValid(veh_id); + GroupID new_g = group_id; if (v == nullptr || (!Group::IsValidID(new_g) && !IsDefaultGroupID(new_g) && new_g != NEW_GROUP)) return CMD_ERROR; @@ -525,7 +513,7 @@ CommandCost CmdAddVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, u if (new_g == NEW_GROUP) { /* Create new group. */ - CommandCost ret = CmdCreateGroup(flags, 0, v->type, INVALID_GROUP, {}); + CommandCost ret = CmdCreateGroup(flags, v->type, INVALID_GROUP); if (ret.Failed()) return ret; new_g = _new_group_id; @@ -534,7 +522,7 @@ CommandCost CmdAddVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, u if (flags & DC_EXEC) { AddVehicleToGroup(v, new_g); - if (HasBit(p2, 31)) { + if (add_shared) { /* Add vehicles in the shared order list as well. */ for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { if (v2->group_id != new_g) AddVehicleToGroup(v2, new_g); @@ -559,17 +547,12 @@ CommandCost CmdAddVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, u /** * Add all shared vehicles of all vehicles from a group * @param flags type of operation - * @param tile unused - * @param p1 index of group array - * - p1 bit 0-15 : GroupID - * @param p2 type of vehicles - * @param text unused + * @param id_g index of group + * @param type type of vehicles * @return the cost of this operation or an error */ -CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, GroupID id_g, VehicleType type) { - VehicleType type = Extract(p2); - GroupID id_g = p1; if (!Group::IsValidID(id_g) || !IsCompanyBuildableVehicleType(type)) return CMD_ERROR; if (flags & DC_EXEC) { @@ -581,7 +564,7 @@ CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 /* For each shared vehicles add it to the group */ for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { - if (v2->group_id != id_g) Command::Do(flags, tile, id_g, v2->index, text); + if (v2->group_id != id_g) Command::Do(flags, id_g, v2->index, false); } } } @@ -596,17 +579,12 @@ CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, TileIndex tile, uint32 /** * Remove all vehicles from a group * @param flags type of operation - * @param tile unused - * @param p1 index of group array - * - p1 bit 0-15 : GroupID - * @param p2 unused - * @param text unused + * @param group_id index of group * @return the cost of this operation or an error */ -CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, GroupID group_id) { - GroupID old_g = p1; - Group *g = Group::GetIfValid(old_g); + Group *g = Group::GetIfValid(group_id); if (g == nullptr || g->owner != _current_company) return CMD_ERROR; @@ -614,10 +592,10 @@ CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, TileIndex tile, uint3 /* Find each Vehicle that belongs to the group old_g and add it to the default group */ for (const Vehicle *v : Vehicle::Iterate()) { if (v->IsPrimaryVehicle()) { - if (v->group_id != old_g) continue; + if (v->group_id != group_id) continue; /* Add The Vehicle to the default group */ - Command::Do(flags,tile, DEFAULT_GROUP, v->index, text); + Command::Do(flags, DEFAULT_GROUP, v->index, false); } } @@ -630,18 +608,13 @@ CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, TileIndex tile, uint3 /** * Set the livery for a vehicle group. * @param flags Command flags. - * @param tile Unused. - * @param p1 - * - p1 bit 0-15 Group ID. - * @param p2 - * - p2 bit 8 Set secondary instead of primary colour - * - p2 bit 16-23 Colour. + * @param group_id Group ID. + * @param primary Set primary instead of secondary colour + * @param colour Colour. */ -CommandCost CmdSetGroupLivery(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGroupLivery(DoCommandFlag flags, GroupID group_id, bool primary, Colours colour) { - Group *g = Group::GetIfValid(p1); - bool primary = !HasBit(p2, 8); - Colours colour = Extract(p2); + Group *g = Group::GetIfValid(group_id); if (g == nullptr || g->owner != _current_company) return CMD_ERROR; @@ -689,27 +662,21 @@ static void SetGroupFlag(Group *g, GroupFlags flag, bool set, bool children) * (Un)set group flag from a group * @param flags type of operation * @param tile unused - * @param p1 index of group array - * - p1 bit 0-15 : GroupID - * - p1 bit 16-18 : Flag to set, by value not bit. - * @param p2 - * - p2 bit 0 : 1 to set or 0 to clear protection. - * - p2 bit 1 : 1 to apply to sub-groups. - * @param text unused + * @param group_id index of group array + * @param flag flag to set, by value not bit. + * @param value value to set the flag to. + * @param recursive to apply to sub-groups. * @return the cost of this operation or an error */ -CommandCost CmdSetGroupFlag(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGroupFlag(DoCommandFlag flags, GroupID group_id, GroupFlags flag, bool value, bool recursive) { - Group *g = Group::GetIfValid(GB(p1, 0, 16)); + Group *g = Group::GetIfValid(group_id); if (g == nullptr || g->owner != _current_company) return CMD_ERROR; - /* GroupFlags are stored in as an 8 bit bitfield but passed here by value, - * so 3 bits is sufficient to cover each possible value. */ - GroupFlags flag = (GroupFlags)GB(p1, 16, 3); if (flag >= GroupFlags::GF_END) return CMD_ERROR; if (flags & DC_EXEC) { - SetGroupFlag(g, flag, HasBit(p2, 0), HasBit(p2, 1)); + SetGroupFlag(g, flag, value, recursive); SetWindowDirty(GetWindowClassForVehicleType(g->vehicle_type), VehicleListIdentifier(VL_GROUP_LIST, g->vehicle_type, _current_company).Pack()); InvalidateWindowData(WC_REPLACE_VEHICLE, g->vehicle_type); diff --git a/src/group_cmd.h b/src/group_cmd.h index 7f3496cc9c..70610de756 100644 --- a/src/group_cmd.h +++ b/src/group_cmd.h @@ -11,15 +11,26 @@ #define GROUP_CMD_H #include "command_type.h" +#include "group_type.h" +#include "vehicle_type.h" -CommandProc CmdCreateGroup; -CommandProc CmdAlterGroup; -CommandProc CmdDeleteGroup; -CommandProc CmdAddVehicleGroup; -CommandProc CmdAddSharedVehicleGroup; -CommandProc CmdRemoveAllVehiclesGroup; -CommandProc CmdSetGroupFlag; -CommandProc CmdSetGroupLivery; +enum Colours : byte; +enum GroupFlags : uint8; + +/** Action for \c CmdAlterGroup. */ +enum class AlterGroupMode : byte { + Rename, ///< Change group name. + SetParent, ///< Change group parent. +}; + +CommandCost CmdCreateGroup(DoCommandFlag flags, VehicleType vt, GroupID parent_group); +CommandCost CmdAlterGroup(DoCommandFlag flags, AlterGroupMode mode, GroupID group_id, GroupID parent_id, const std::string &text); +CommandCost CmdDeleteGroup(DoCommandFlag flags, GroupID group_id); +CommandCost CmdAddVehicleGroup(DoCommandFlag flags, GroupID group_id, VehicleID veh_id, bool add_shared); +CommandCost CmdAddSharedVehicleGroup(DoCommandFlag flags, GroupID id_g, VehicleType type); +CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlag flags, GroupID group_id); +CommandCost CmdSetGroupFlag(DoCommandFlag flags, GroupID group_id, GroupFlags flag, bool value, bool recursive); +CommandCost CmdSetGroupLivery(DoCommandFlag flags, GroupID group_id, bool primary, Colours colour); DEF_CMD_TRAIT(CMD_CREATE_GROUP, CmdCreateGroup, 0, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_DELETE_GROUP, CmdDeleteGroup, 0, CMDT_ROUTE_MANAGEMENT) diff --git a/src/group_gui.cpp b/src/group_gui.cpp index d3d270f314..3175909f0f 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -642,7 +642,7 @@ public: if (confirmed) { VehicleGroupWindow *w = (VehicleGroupWindow*)win; w->vli.index = ALL_GROUP; - Command::Post(STR_ERROR_GROUP_CAN_T_DELETE, 0, w->group_confirm, 0, {}); + Command::Post(STR_ERROR_GROUP_CAN_T_DELETE, w->group_confirm); } } @@ -773,7 +773,7 @@ public: } case WID_GL_CREATE_GROUP: { // Create a new group - Command::Post(STR_ERROR_GROUP_CAN_T_CREATE, CcCreateGroup, 0, this->vli.vtype, this->vli.index, {}); + Command::Post(STR_ERROR_GROUP_CAN_T_CREATE, CcCreateGroup, this->vli.vtype, this->vli.index); break; } @@ -809,7 +809,7 @@ public: case WID_GL_REPLACE_PROTECTION: { const Group *g = Group::GetIfValid(this->vli.index); if (g != nullptr) { - Command::Post(0, this->vli.index | (GroupFlags::GF_REPLACE_PROTECTION << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION) ? 0 : 1) | (_ctrl_pressed << 1), {}); + Command::Post(this->vli.index, GroupFlags::GF_REPLACE_PROTECTION, !HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION), _ctrl_pressed); } break; } @@ -824,7 +824,7 @@ public: case WID_GL_ALL_VEHICLES: // All vehicles case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles if (g->parent != INVALID_GROUP) { - Command::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), INVALID_GROUP, {}); + Command::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, AlterGroupMode::SetParent, this->group_sel, INVALID_GROUP, {}); } this->group_sel = INVALID_GROUP; @@ -837,7 +837,7 @@ public: GroupID new_g = id_g >= this->groups.size() ? INVALID_GROUP : this->groups[id_g]->index; if (this->group_sel != new_g && g->parent != new_g) { - Command::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, 0, this->group_sel | (1 << 16), new_g, {}); + Command::Post(STR_ERROR_GROUP_CAN_T_SET_PARENT, AlterGroupMode::SetParent, this->group_sel, new_g, {}); } this->group_sel = INVALID_GROUP; @@ -852,7 +852,7 @@ public: { switch (widget) { case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles - Command::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, 0, DEFAULT_GROUP, this->vehicle_sel | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), {}); + Command::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, DEFAULT_GROUP, this->vehicle_sel, _ctrl_pressed || this->grouping == GB_SHARED_ORDERS); this->vehicle_sel = INVALID_VEHICLE; this->group_over = INVALID_GROUP; @@ -869,7 +869,7 @@ public: uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP); GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; - Command::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex | (_ctrl_pressed || this->grouping == GB_SHARED_ORDERS ? 1 << 31 : 0), {}); + Command::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex, _ctrl_pressed || this->grouping == GB_SHARED_ORDERS); break; } @@ -924,7 +924,7 @@ public: void OnQueryTextFinished(char *str) override { - if (str != nullptr) Command::Post(STR_ERROR_GROUP_CAN_T_RENAME, 0, this->group_rename, 0, str); + if (str != nullptr) Command::Post(STR_ERROR_GROUP_CAN_T_RENAME, AlterGroupMode::Rename, this->group_rename, 0, str); this->group_rename = INVALID_GROUP; } @@ -961,12 +961,12 @@ public: case ADI_ADD_SHARED: // Add shared Vehicles assert(Group::IsValidID(this->vli.index)); - Command::Post(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE, 0, this->vli.index, this->vli.vtype, {}); + Command::Post(STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE, this->vli.index, this->vli.vtype); break; case ADI_REMOVE_ALL: // Remove all Vehicles from the selected group assert(Group::IsValidID(this->vli.index)); - Command::Post(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, 0, this->vli.index, 0, {}); + Command::Post(STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES, this->vli.index); break; default: NOT_REACHED(); } @@ -1161,10 +1161,10 @@ void CcCreateGroup(Commands cmd, const CommandCost &result, TileIndex tile, cons { if (result.Failed()) return; - auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); - assert(p1 <= VEH_AIRCRAFT); + auto [vt, parent_group] = EndianBufferReader::ToValue::Args>(data); + assert(vt <= VEH_AIRCRAFT); - CcCreateGroup((VehicleType)p1); + CcCreateGroup(vt); } /** @@ -1178,10 +1178,10 @@ void CcAddVehicleNewGroup(Commands cmd, const CommandCost &result, TileIndex til { if (result.Failed()) return; - auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); - assert(Vehicle::IsValidID(GB(p2, 0, 20))); + auto [group_id, veh_id, shared] = EndianBufferReader::ToValue::Args>(data); + assert(Vehicle::IsValidID(veh_id)); - CcCreateGroup(Vehicle::Get(GB(p2, 0, 20))->type); + CcCreateGroup(Vehicle::Get(veh_id)->type); } /** diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 1818029f22..46a55991da 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -90,7 +90,7 @@ void OrderBackup::DoRestore(Vehicle *v) if (v->cur_implicit_order_index >= v->GetNumOrders()) v->cur_implicit_order_index = v->cur_real_order_index; /* Restore vehicle group */ - Command::Do(DC_EXEC, 0, this->group, v->index, {}); + Command::Do(DC_EXEC, this->group, v->index, false); } /** diff --git a/src/script/api/script_group.cpp b/src/script/api/script_group.cpp index f4535c35e4..5047dc5c0e 100644 --- a/src/script/api/script_group.cpp +++ b/src/script/api/script_group.cpp @@ -31,7 +31,7 @@ /* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id) { - if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnGroupID, 0, (::VehicleType)vehicle_type, parent_group_id, {})) return GROUP_INVALID; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnGroupID, (::VehicleType)vehicle_type, parent_group_id)) return GROUP_INVALID; /* In case of test-mode, we return GroupID 0 */ return (ScriptGroup::GroupID)0; @@ -41,7 +41,7 @@ { EnforcePrecondition(false, IsValidGroup(group_id)); - return ScriptObject::Command::Do(0, group_id, 0, {}); + return ScriptObject::Command::Do(group_id); } /* static */ ScriptVehicle::VehicleType ScriptGroup::GetVehicleType(GroupID group_id) @@ -61,7 +61,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_GROUP_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::Command::Do(0, group_id, 0, text); + return ScriptObject::Command::Do(AlterGroupMode::Rename, group_id, 0, text); } /* static */ char *ScriptGroup::GetName(GroupID group_id) @@ -77,7 +77,7 @@ EnforcePrecondition(false, IsValidGroup(group_id)); EnforcePrecondition(false, IsValidGroup(parent_group_id)); - return ScriptObject::Command::Do(0, group_id | 1 << 16, parent_group_id, {}); + return ScriptObject::Command::Do(AlterGroupMode::SetParent, group_id, parent_group_id, {}); } /* static */ ScriptGroup::GroupID ScriptGroup::GetParent(GroupID group_id) @@ -92,7 +92,7 @@ { EnforcePrecondition(false, IsValidGroup(group_id)); - return ScriptObject::Command::Do(0, group_id | GroupFlags::GF_REPLACE_PROTECTION, enable ? 1 : 0, {}); + return ScriptObject::Command::Do(group_id, GroupFlags::GF_REPLACE_PROTECTION, enable, false); } /* static */ bool ScriptGroup::GetAutoReplaceProtection(GroupID group_id) @@ -123,7 +123,7 @@ EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT); EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); - return ScriptObject::Command::Do(0, group_id, vehicle_id, {}); + return ScriptObject::Command::Do(group_id, vehicle_id, false); } /* static */ bool ScriptGroup::EnableWagonRemoval(bool enable_removal) @@ -143,7 +143,7 @@ EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL); EnforcePrecondition(false, ScriptEngine::IsBuildable(engine_id_new)); - return ScriptObject::Command::Do(0, group_id << 16, (engine_id_new << 16) | engine_id_old, {}); + return ScriptObject::Command::Do(group_id, engine_id_old, engine_id_new, false); } /* static */ EngineID ScriptGroup::GetEngineReplacement(GroupID group_id, EngineID engine_id) @@ -157,7 +157,7 @@ { EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL); - return ScriptObject::Command::Do(0, group_id << 16, (::INVALID_ENGINE << 16) | engine_id, {}); + return ScriptObject::Command::Do(group_id, engine_id, ::INVALID_ENGINE, false); } /* static */ Money ScriptGroup::GetProfitThisYear(GroupID group_id) @@ -207,14 +207,14 @@ { EnforcePrecondition(false, IsValidGroup(group_id)); - return ScriptObject::Command::Do(0, group_id, colour << 16, {}); + return ScriptObject::Command::Do(group_id, true, (::Colours)colour); } /* static */ bool ScriptGroup::SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour) { EnforcePrecondition(false, IsValidGroup(group_id)); - return ScriptObject::Command::Do(0, group_id, (1 << 8) | (colour << 16), {}); + return ScriptObject::Command::Do(group_id, false, (::Colours)colour); } /* static */ ScriptCompany::Colours ScriptGroup::GetPrimaryColour(GroupID group_id) diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 9a66053d33..d5d39b6e8d 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1059,7 +1059,7 @@ void CallVehicleTicks() const Company *c = Company::Get(_current_company); SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money)); - CommandCost res = Command::Do(DC_EXEC, 0, v->index, 0, {}); + CommandCost res = Command::Do(DC_EXEC, v->index); SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money)); if (!IsLocalCompany()) continue; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 100b309f90..2f6a01cab7 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -707,7 +707,7 @@ CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, Vehicle /* Ensure that the vehicle completely in the depot */ if (!v->IsChainInDepot()) continue; - CommandCost ret = Command::Do(flags, 0, v->index, 0, {}); + CommandCost ret = Command::Do(flags, v->index); if (ret.Succeeded()) cost.AddCost(ret); } @@ -891,7 +891,7 @@ CommandCost CmdCloneVehicle(DoCommandFlag flags, TileIndex tile, VehicleID veh_i if (flags & DC_EXEC) { /* Cloned vehicles belong to the same group */ - Command::Do(flags, 0, v_front->group_id, w_front->index, {}); + Command::Do(flags, v_front->group_id, w_front->index, false); } From 1a42a8a5d50e917a3b7158feadc70205cf912cba Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Wed, 17 Nov 2021 23:54:46 +0100 Subject: [PATCH 29/60] Codechange: Un-bitstuff town-related commands. --- src/cargotype.h | 2 +- src/script/api/script_town.cpp | 16 ++-- src/town_cmd.cpp | 140 ++++++++++++++------------------- src/town_cmd.h | 22 +++--- src/town_gui.cpp | 10 +-- src/town_type.h | 2 +- 6 files changed, 86 insertions(+), 106 deletions(-) diff --git a/src/cargotype.h b/src/cargotype.h index 22c1bf7f54..54d24f1d7a 100644 --- a/src/cargotype.h +++ b/src/cargotype.h @@ -23,7 +23,7 @@ typedef uint32 CargoLabel; /** Town growth effect when delivering cargo. */ -enum TownEffect { +enum TownEffect : byte { TE_BEGIN = 0, TE_NONE = TE_BEGIN, ///< Cargo has no effect. TE_PASSENGERS, ///< Cargo behaves passenger-like. diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp index e3fb26e893..78a1734441 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -52,7 +52,7 @@ } EnforcePrecondition(false, IsValidTown(town_id)); - return ScriptObject::Command::Do(0, town_id, 0, text != nullptr ? std::string{ text } : std::string{}); + return ScriptObject::Command::Do(town_id, text != nullptr ? std::string{ text } : std::string{}); } /* static */ bool ScriptTown::SetText(TownID town_id, Text *text) @@ -66,7 +66,7 @@ } EnforcePrecondition(false, IsValidTown(town_id)); - return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id, 0, encoded_text != nullptr ? std::string{ encoded_text } : std::string{}); + return ScriptObject::Command::Do(town_id, encoded_text != nullptr ? std::string{ encoded_text } : std::string{}); } /* static */ int32 ScriptTown::GetPopulation(TownID town_id) @@ -134,7 +134,7 @@ EnforcePrecondition(false, IsValidTown(town_id)); EnforcePrecondition(false, ScriptCargo::IsValidTownEffect(towneffect_id)); - return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id | (towneffect_id << 16), goal, {}); + return ScriptObject::Command::Do(town_id, (::TownEffect)towneffect_id, goal); } /* static */ uint32 ScriptTown::GetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id) @@ -177,7 +177,7 @@ break; } - return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id, growth_rate, {}); + return ScriptObject::Command::Do(town_id, growth_rate); } /* static */ int32 ScriptTown::GetGrowthRate(TownID town_id) @@ -267,7 +267,7 @@ EnforcePrecondition(false, IsValidTown(town_id)); EnforcePrecondition(false, IsActionAvailable(town_id, town_action)); - return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id, town_action, {}); + return ScriptObject::Command::Do(town_id, town_action); } /* static */ bool ScriptTown::ExpandTown(TownID town_id, int houses) @@ -276,7 +276,7 @@ EnforcePrecondition(false, IsValidTown(town_id)); EnforcePrecondition(false, houses > 0); - return ScriptObject::Command::Do(::Town::Get(town_id)->xy, town_id, houses, {}); + return ScriptObject::Command::Do(town_id, houses); } /* static */ bool ScriptTown::FoundTown(TileIndex tile, TownSize size, bool city, RoadLayout layout, Text *name) @@ -306,7 +306,7 @@ return false; } - return ScriptObject::Command::Do(tile, size | (city ? 1 << 2 : 0) | layout << 3, townnameparts, text != nullptr ? std::string{ text } : std::string{}); + return ScriptObject::Command::Do(tile, (::TownSize)size, city, (::TownLayout)layout, false, townnameparts, text != nullptr ? std::string{ text } : std::string{}); } /* static */ ScriptTown::TownRating ScriptTown::GetRating(TownID town_id, ScriptCompany::CompanyID company_id) @@ -361,7 +361,7 @@ uint16 p2 = 0; memcpy(&p2, &new_rating, sizeof(p2)); - return ScriptObject::Command::Do(0, town_id | (company_id << 16), p2, {}); + return ScriptObject::Command::Do(town_id, (::CompanyID)company_id, p2); } /* static */ int ScriptTown::GetAllowedNoise(TownID town_id) diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 7a564d48ab..7ef07aa6aa 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1929,22 +1929,17 @@ static bool IsUniqueTownName(const std::string &name) * Create a new town. * @param flags type of operation * @param tile coordinates where town is built - * @param p1 0..1 size of the town (@see TownSize) - * 2 true iff it should be a city - * 3..5 town road layout (@see TownLayout) - * 6 use random location (randomize \c tile ) - * @param p2 town name parts + * @param size size of the town (@see TownSize) + * @param city true iff it should be a city + * @param layout town road layout (@see TownLayout) + * @param random_location use random location (randomize \c tile ) + * @param townnameparts town name parts * @param text Custom name for the town. If empty, the town name parts will be used. * @return the cost of this operation or an error */ -CommandCost CmdFoundTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdFoundTown(DoCommandFlag flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32 townnameparts, const std::string &text) { - TownSize size = Extract(p1); - bool city = HasBit(p1, 2); - TownLayout layout = Extract(p1); TownNameParams par(_settings_game.game_creation.town_name); - bool random = HasBit(p1, 6); - uint32 townnameparts = p2; if (size >= TSZ_END) return CMD_ERROR; if (layout >= NUM_TLS) return CMD_ERROR; @@ -1953,11 +1948,11 @@ CommandCost CmdFoundTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) { if (_settings_game.economy.found_town == TF_FORBIDDEN) return CMD_ERROR; if (size == TSZ_LARGE) return CMD_ERROR; - if (random) return CMD_ERROR; + if (random_location) return CMD_ERROR; if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT && layout != _settings_game.economy.town_layout) { return CMD_ERROR; } - } else if (_current_company == OWNER_DEITY && random) { + } else if (_current_company == OWNER_DEITY && random_location) { /* Random parameter is not allowed for Game Scripts. */ return CMD_ERROR; } @@ -1974,7 +1969,7 @@ CommandCost CmdFoundTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /* Allocate town struct */ if (!Town::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_TOWNS); - if (!random) { + if (!random_location) { CommandCost ret = TownCanBePlacedHere(tile); if (ret.Failed()) return ret; } @@ -1998,7 +1993,7 @@ CommandCost CmdFoundTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 Backup old_generating_world(_generating_world, true, FILE_LINE); UpdateNearestTownForRoadTiles(true); Town *t; - if (random) { + if (random_location) { t = CreateRandomTown(20, townnameparts, size, city, layout); if (t == nullptr) { cost = CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN); @@ -2019,7 +2014,7 @@ CommandCost CmdFoundTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 if (_game_mode != GM_EDITOR) { /* 't' can't be nullptr since 'random' is false outside scenedit */ - assert(!random); + assert(!random_location); if (_current_company == OWNER_DEITY) { SetDParam(0, t->index); @@ -2184,7 +2179,7 @@ static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size if (t->cache.population > 0) return t; Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); - [[maybe_unused]] CommandCost rc = Command::Do(DC_EXEC, t->xy, t->index, 0, {}); + [[maybe_unused]] CommandCost rc = Command::Do(DC_EXEC, t->index); cur_company.Restore(); assert(rc.Succeeded()); @@ -2740,15 +2735,13 @@ void ClearTownHouse(Town *t, TileIndex tile) /** * Rename a town (server-only). * @param flags type of operation - * @param tile unused - * @param p1 town ID to rename - * @param p2 unused + * @param town_id town ID to rename * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameTown(DoCommandFlag flags, TownID town_id, const std::string &text) { - Town *t = Town::GetIfValid(p1); + Town *t = Town::GetIfValid(town_id); if (t == nullptr) return CMD_ERROR; bool reset = text.empty(); @@ -2793,21 +2786,19 @@ const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect) * @param flags Type of operation. * @param tile Unused. * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 15) - Town ID to cargo game of. - * - p1 = (bit 16 - 23) - TownEffect to change the game of. - * @param p2 The new goal value. + * @param town_id Town ID to cargo game of. + * @param te TownEffect to change the game of. + * @param goal The new goal value. * @param text Unused. * @return Empty cost or an error. */ -CommandCost CmdTownCargoGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTownCargoGoal(DoCommandFlag flags, TownID town_id, TownEffect te, uint32 goal) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - TownEffect te = (TownEffect)GB(p1, 16, 8); if (te < TE_BEGIN || te >= TE_END) return CMD_ERROR; - uint16 index = GB(p1, 0, 16); - Town *t = Town::GetIfValid(index); + Town *t = Town::GetIfValid(town_id); if (t == nullptr) return CMD_ERROR; /* Validate if there is a cargo which is the requested TownEffect */ @@ -2815,9 +2806,9 @@ CommandCost CmdTownCargoGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uin if (cargo == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { - t->goal[te] = p2; + t->goal[te] = goal; UpdateTownGrowth(t); - InvalidateWindowData(WC_TOWN_VIEW, index); + InvalidateWindowData(WC_TOWN_VIEW, town_id); } return CommandCost(); @@ -2826,22 +2817,20 @@ CommandCost CmdTownCargoGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uin /** * Set a custom text in the Town window. * @param flags Type of operation. - * @param tile Unused. - * @param p1 Town ID to change the text of. - * @param p2 Unused. + * @param town_id Town ID to change the text of. * @param text The new text (empty to remove the text). * @return Empty cost or an error. */ -CommandCost CmdTownSetText(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTownSetText(DoCommandFlag flags, TownID town_id, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - Town *t = Town::GetIfValid(p1); + Town *t = Town::GetIfValid(town_id); if (t == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { t->text.clear(); if (!text.empty()) t->text = text; - InvalidateWindowData(WC_TOWN_VIEW, p1); + InvalidateWindowData(WC_TOWN_VIEW, town_id); } return CommandCost(); @@ -2850,38 +2839,35 @@ CommandCost CmdTownSetText(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 /** * Change the growth rate of the town. * @param flags Type of operation. - * @param tile Unused. - * @param p1 Town ID to cargo game of. - * @param p2 Amount of days between growth, or TOWN_GROWTH_RATE_NONE, or 0 to reset custom growth rate. - * @param text Unused. + * @param town_id Town ID to cargo game of. + * @param growth_rate Amount of days between growth, or TOWN_GROWTH_RATE_NONE, or 0 to reset custom growth rate. * @return Empty cost or an error. */ -CommandCost CmdTownGrowthRate(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTownGrowthRate(DoCommandFlag flags, TownID town_id, uint16 growth_rate) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - if (GB(p2, 16, 16) != 0) return CMD_ERROR; - Town *t = Town::GetIfValid(p1); + Town *t = Town::GetIfValid(town_id); if (t == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { - if (p2 == 0) { + if (growth_rate == 0) { /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */ ClrBit(t->flags, TOWN_CUSTOM_GROWTH); } else { uint old_rate = t->growth_rate; if (t->grow_counter >= old_rate) { /* This also catches old_rate == 0 */ - t->grow_counter = p2; + t->grow_counter = growth_rate; } else { /* Scale grow_counter, so half finished houses stay half finished */ - t->grow_counter = t->grow_counter * p2 / old_rate; + t->grow_counter = t->grow_counter * growth_rate / old_rate; } - t->growth_rate = p2; + t->growth_rate = growth_rate; SetBit(t->flags, TOWN_CUSTOM_GROWTH); } UpdateTownGrowth(t); - InvalidateWindowData(WC_TOWN_VIEW, p1); + InvalidateWindowData(WC_TOWN_VIEW, town_id); } return CommandCost(); @@ -2890,24 +2876,21 @@ CommandCost CmdTownGrowthRate(DoCommandFlag flags, TileIndex tile, uint32 p1, ui /** * Change the rating of a company in a town * @param flags Type of operation. - * @param tile Unused. - * @param p1 Bit 0..15 = Town ID to change, bit 16..23 = Company ID to change. - * @param p2 Bit 0..15 = New rating of company (signed int16). - * @param text Unused. + * @param town_id Town ID to change, bit 16..23 = + * @param company_id Company ID to change. + * @param rating New rating of company (signed int16). * @return Empty cost or an error. */ -CommandCost CmdTownRating(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTownRating(DoCommandFlag flags, TownID town_id, CompanyID company_id, int16 rating) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - TownID town_id = (TownID)GB(p1, 0, 16); Town *t = Town::GetIfValid(town_id); if (t == nullptr) return CMD_ERROR; - CompanyID company_id = (CompanyID)GB(p1, 16, 8); if (!Company::IsValidID(company_id)) return CMD_ERROR; - int16 new_rating = Clamp((int16)GB(p2, 0, 16), RATING_MINIMUM, RATING_MAXIMUM); + int16 new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM); if (flags & DC_EXEC) { t->ratings[company_id] = new_rating; InvalidateWindowData(WC_TOWN_AUTHORITY, town_id); @@ -2919,21 +2902,19 @@ CommandCost CmdTownRating(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /** * Expand a town (scenario editor only). * @param flags Type of operation. - * @param tile Unused. - * @param p1 Town ID to expand. - * @param p2 Amount to grow, or 0 to grow a random size up to the current amount of houses. - * @param text Unused. + * @param TownID Town ID to expand. + * @param grow_amount Amount to grow, or 0 to grow a random size up to the current amount of houses. * @return Empty cost or an error. */ -CommandCost CmdExpandTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdExpandTown(DoCommandFlag flags, TownID town_id, uint32 grow_amount) { if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR; - Town *t = Town::GetIfValid(p1); + Town *t = Town::GetIfValid(town_id); if (t == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { /* The more houses, the faster we grow */ - if (p2 == 0) { + if (grow_amount == 0) { uint amount = RandomRange(ClampToU16(t->cache.num_houses / 10)) + 3; t->cache.num_houses += amount; UpdateTownRadius(t); @@ -2943,7 +2924,7 @@ CommandCost CmdExpandTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 t->cache.num_houses -= amount; } else { - for (; p2 > 0; p2--) { + for (; grow_amount > 0; grow_amount--) { /* Try several times to grow, as we are really suppose to grow */ for (uint i = 0; i < 25; i++) if (GrowTown(t)) break; } @@ -2959,16 +2940,13 @@ CommandCost CmdExpandTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /** * Delete a town (scenario editor or worldgen only). * @param flags Type of operation. - * @param tile Unused. - * @param p1 Town ID to delete. - * @param p2 Unused. - * @param text Unused. + * @param town_id Town ID to delete. * @return Empty cost or an error. */ -CommandCost CmdDeleteTown(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id) { if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR; - Town *t = Town::GetIfValid(p1); + Town *t = Town::GetIfValid(town_id); if (t == nullptr) return CMD_ERROR; /* Stations refer to towns. */ @@ -3345,26 +3323,24 @@ uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t) * This performs an action such as advertising, building a statue, funding buildings, * but also bribing the town-council * @param flags type of operation - * @param tile unused - * @param p1 town to do the action at - * @param p2 action to perform, @see _town_action_proc for the list of available actions - * @param text unused + * @param town_id town to do the action at + * @param action action to perform, @see _town_action_proc for the list of available actions * @return the cost of this operation or an error */ -CommandCost CmdDoTownAction(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDoTownAction(DoCommandFlag flags, TownID town_id, uint8 action) { - Town *t = Town::GetIfValid(p1); - if (t == nullptr || p2 >= lengthof(_town_action_proc)) return CMD_ERROR; + Town *t = Town::GetIfValid(town_id); + if (t == nullptr || action >= lengthof(_town_action_proc)) return CMD_ERROR; - if (!HasBit(GetMaskOfTownActions(nullptr, _current_company, t), p2)) return CMD_ERROR; + if (!HasBit(GetMaskOfTownActions(nullptr, _current_company, t), action)) return CMD_ERROR; - CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * _town_action_costs[p2] >> 8); + CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * _town_action_costs[action] >> 8); - CommandCost ret = _town_action_proc[p2](t, flags); + CommandCost ret = _town_action_proc[action](t, flags); if (ret.Failed()) return ret; if (flags & DC_EXEC) { - SetWindowDirty(WC_TOWN_AUTHORITY, p1); + SetWindowDirty(WC_TOWN_AUTHORITY, town_id); } return cost; diff --git a/src/town_cmd.h b/src/town_cmd.h index 7842e7ddaa..4c9782e487 100644 --- a/src/town_cmd.h +++ b/src/town_cmd.h @@ -11,16 +11,20 @@ #define TOWN_CMD_H #include "command_type.h" +#include "company_type.h" +#include "town_type.h" -CommandProc CmdFoundTown; -CommandProc CmdRenameTown; -CommandProc CmdDoTownAction; -CommandProc CmdTownGrowthRate; -CommandProc CmdTownRating; -CommandProc CmdTownCargoGoal; -CommandProc CmdTownSetText; -CommandProc CmdExpandTown; -CommandProc CmdDeleteTown; +enum TownEffect : byte; + +CommandCost CmdFoundTown(DoCommandFlag flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32 townnameparts, const std::string &text); +CommandCost CmdRenameTown(DoCommandFlag flags, TownID town_id, const std::string &text); +CommandCost CmdDoTownAction(DoCommandFlag flags, TownID town_id, uint8 action); +CommandCost CmdTownGrowthRate(DoCommandFlag flags, TownID town_id, uint16 growth_rate); +CommandCost CmdTownRating(DoCommandFlag flags, TownID town_id, CompanyID company_id, int16 rating); +CommandCost CmdTownCargoGoal(DoCommandFlag flags, TownID town_id, TownEffect te, uint32 goal); +CommandCost CmdTownSetText(DoCommandFlag flags, TownID town_id, const std::string &text); +CommandCost CmdExpandTown(DoCommandFlag flags, TownID town_id, uint32 grow_amount); +CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id); DEF_CMD_TRAIT(CMD_FOUND_TOWN, CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // founding random town can fail only in exec run DEF_CMD_TRAIT(CMD_RENAME_TOWN, CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT) diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 6e955e103e..90aa588552 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -288,7 +288,7 @@ public: } case WID_TA_EXECUTE: - Command::Post(STR_ERROR_CAN_T_DO_THIS, this->town->xy, this->window_number, this->sel_index, {}); + Command::Post(STR_ERROR_CAN_T_DO_THIS, this->town->xy, this->window_number, this->sel_index); break; } } @@ -475,12 +475,12 @@ public: _warn_town_no_roads = true; } - Command::Post(STR_ERROR_CAN_T_EXPAND_TOWN, 0, this->window_number, 0, {}); + Command::Post(STR_ERROR_CAN_T_EXPAND_TOWN, this->window_number, 0); break; } case WID_TV_DELETE: // delete town - only available on Scenario editor - Command::Post(STR_ERROR_TOWN_CAN_T_DELETE, 0, this->window_number, 0, {}); + Command::Post(STR_ERROR_TOWN_CAN_T_DELETE, this->window_number); break; } } @@ -562,7 +562,7 @@ public: { if (str == nullptr) return; - Command::Post(STR_ERROR_CAN_T_RENAME_TOWN, 0, this->window_number, 0, str); + Command::Post(STR_ERROR_CAN_T_RENAME_TOWN, this->window_number, str); } }; @@ -1164,7 +1164,7 @@ public: } bool success = Command::Post(errstr, cc, - tile, this->town_size | this->city << 2 | this->town_layout << 3 | random << 6, townnameparts, name); + tile, this->town_size, this->city, this->town_layout, random, townnameparts, name); /* Rerandomise name, if success and no cost-estimation. */ if (success && !_shift_pressed) this->RandomTownName(); diff --git a/src/town_type.h b/src/town_type.h index f373a3c043..3ea1a4e983 100644 --- a/src/town_type.h +++ b/src/town_type.h @@ -16,7 +16,7 @@ typedef uint16 TownID; struct Town; /** Supported initial town sizes */ -enum TownSize { +enum TownSize : byte { TSZ_SMALL, ///< Small town. TSZ_MEDIUM, ///< Medium town. TSZ_LARGE, ///< Large town. From e6e69d528921ab731c4c38ee708ff31b7055fd27 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sat, 20 Nov 2021 22:30:56 +0100 Subject: [PATCH 30/60] Codechange: Un-bitstuff goal and story page commands. --- src/goal.cpp | 115 +++++++++++---------------- src/goal_cmd.h | 16 ++-- src/goal_gui.cpp | 6 +- src/script/api/script_goal.cpp | 16 ++-- src/script/api/script_story_page.cpp | 17 ++-- src/story.cpp | 93 +++++++--------------- src/story_cmd.h | 22 ++--- src/story_gui.cpp | 6 +- src/story_type.h | 1 + 9 files changed, 119 insertions(+), 173 deletions(-) diff --git a/src/goal.cpp b/src/goal.cpp index a60853829d..99322ec2cf 100644 --- a/src/goal.cpp +++ b/src/goal.cpp @@ -36,49 +36,44 @@ INSTANTIATE_POOL_METHODS(Goal) /** * Create a new goal. * @param flags type of operation - * @param tile unused. - * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 7) - GoalType of destination. - * - p1 = (bit 8 - 15) - Company for which this goal is. - * @param p2 GoalTypeID of destination. + * @param company Company for which this goal is. + * @param type GoalType of destination. + * @param dest GoalTypeID of destination. * @param text Text of the goal. * @return the cost of this operation or an error */ -CommandCost CmdCreateGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateGoal(DoCommandFlag flags, CompanyID company, GoalType type, GoalTypeID dest, const std::string &text) { if (!Goal::CanAllocateItem()) return CMD_ERROR; - GoalType type = (GoalType)GB(p1, 0, 8); - CompanyID company = (CompanyID)GB(p1, 8, 8); - if (_current_company != OWNER_DEITY) return CMD_ERROR; if (text.empty()) return CMD_ERROR; if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR; switch (type) { case GT_NONE: - if (p2 != 0) return CMD_ERROR; + if (dest != 0) return CMD_ERROR; break; case GT_TILE: - if (!IsValidTile(p2)) return CMD_ERROR; + if (!IsValidTile(dest)) return CMD_ERROR; break; case GT_INDUSTRY: - if (!Industry::IsValidID(p2)) return CMD_ERROR; + if (!Industry::IsValidID(dest)) return CMD_ERROR; break; case GT_TOWN: - if (!Town::IsValidID(p2)) return CMD_ERROR; + if (!Town::IsValidID(dest)) return CMD_ERROR; break; case GT_COMPANY: - if (!Company::IsValidID(p2)) return CMD_ERROR; + if (!Company::IsValidID(dest)) return CMD_ERROR; break; case GT_STORY_PAGE: { - if (!StoryPage::IsValidID(p2)) return CMD_ERROR; - CompanyID story_company = StoryPage::Get(p2)->company; + if (!StoryPage::IsValidID(dest)) return CMD_ERROR; + CompanyID story_company = StoryPage::Get(dest)->company; if (company == INVALID_COMPANY ? story_company != INVALID_COMPANY : story_company != INVALID_COMPANY && story_company != company) return CMD_ERROR; break; } @@ -89,7 +84,7 @@ CommandCost CmdCreateGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 if (flags & DC_EXEC) { Goal *g = new Goal(); g->type = type; - g->dst = p2; + g->dst = dest; g->company = company; g->text = stredup(text.c_str()); g->progress = nullptr; @@ -111,19 +106,16 @@ CommandCost CmdCreateGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /** * Remove a goal. * @param flags type of operation - * @param tile unused. - * @param p1 GoalID to remove. - * @param p2 unused. - * @param text unused. + * @param goal GoalID to remove. * @return the cost of this operation or an error */ -CommandCost CmdRemoveGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveGoal(DoCommandFlag flags, GoalID goal) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - if (!Goal::IsValidID(p1)) return CMD_ERROR; + if (!Goal::IsValidID(goal)) return CMD_ERROR; if (flags & DC_EXEC) { - Goal *g = Goal::Get(p1); + Goal *g = Goal::Get(goal); CompanyID c = g->company; delete g; @@ -141,20 +133,18 @@ CommandCost CmdRemoveGoal(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 /** * Update goal text of a goal. * @param flags type of operation - * @param tile unused. - * @param p1 GoalID to update. - * @param p2 unused + * @param goal GoalID to update. * @param text Text of the goal. * @return the cost of this operation or an error */ -CommandCost CmdSetGoalText(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGoalText(DoCommandFlag flags, GoalID goal, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - if (!Goal::IsValidID(p1)) return CMD_ERROR; + if (!Goal::IsValidID(goal)) return CMD_ERROR; if (text.empty()) return CMD_ERROR; if (flags & DC_EXEC) { - Goal *g = Goal::Get(p1); + Goal *g = Goal::Get(goal); free(g->text); g->text = stredup(text.c_str()); @@ -171,19 +161,17 @@ CommandCost CmdSetGoalText(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 /** * Update progress text of a goal. * @param flags type of operation - * @param tile unused. - * @param p1 GoalID to update. - * @param p2 unused + * @param goal GoalID to update. * @param text Progress text of the goal. * @return the cost of this operation or an error */ -CommandCost CmdSetGoalProgress(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGoalProgress(DoCommandFlag flags, GoalID goal, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - if (!Goal::IsValidID(p1)) return CMD_ERROR; + if (!Goal::IsValidID(goal)) return CMD_ERROR; if (flags & DC_EXEC) { - Goal *g = Goal::Get(p1); + Goal *g = Goal::Get(goal); free(g->progress); if (text.empty()) { g->progress = nullptr; @@ -204,20 +192,18 @@ CommandCost CmdSetGoalProgress(DoCommandFlag flags, TileIndex tile, uint32 p1, u /** * Update completed state of a goal. * @param flags type of operation - * @param tile unused. - * @param p1 GoalID to update. - * @param p2 completed state. If goal is completed, set to 1, otherwise 0. - * @param text unused + * @param goal GoalID to update. + * @param completed completed state of goal. * @return the cost of this operation or an error */ -CommandCost CmdSetGoalCompleted(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetGoalCompleted(DoCommandFlag flags, GoalID goal, bool completed) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - if (!Goal::IsValidID(p1)) return CMD_ERROR; + if (!Goal::IsValidID(goal)) return CMD_ERROR; if (flags & DC_EXEC) { - Goal *g = Goal::Get(p1); - g->completed = p2 == 1; + Goal *g = Goal::Get(goal); + g->completed = completed; if (g->company == INVALID_COMPANY) { InvalidateWindowClassesData(WC_GOALS_LIST); @@ -232,27 +218,21 @@ CommandCost CmdSetGoalCompleted(DoCommandFlag flags, TileIndex tile, uint32 p1, /** * Ask a goal related question * @param flags type of operation - * @param tile unused. - * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 15) - Unique ID to use for this question. - * - p1 = (bit 16 - 31) - Company or client for which this question is. - * @param p2 various bitstuffed elements - * - p2 = (bit 0 - 17) - Buttons of the question. - * - p2 = (bit 29 - 30) - Question type. - * - p2 = (bit 31) - Question target: 0 - company, 1 - client. + * @param uniqueid Unique ID to use for this question. + * @param target Company or client for which this question is. + * @param is_client Question target: false - company, true - client. + * @param button_mask Buttons of the question. + * @param type Question type. * @param text Text of the question. * @return the cost of this operation or an error */ -CommandCost CmdGoalQuestion(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdGoalQuestion(DoCommandFlag flags, uint16 uniqueid, uint16 target, bool is_client, uint32 button_mask, GoalQuestionType type, const std::string &text) { - uint16 uniqueid = (uint16)GB(p1, 0, 16); - CompanyID company = (CompanyID)GB(p1, 16, 8); - ClientID client = (ClientID)GB(p1, 16, 16); + CompanyID company = (CompanyID)target; + ClientID client = (ClientID)target; static_assert(GOAL_QUESTION_BUTTON_COUNT < 29); - uint32 button_mask = GB(p2, 0, GOAL_QUESTION_BUTTON_COUNT); - byte type = GB(p2, 29, 2); - bool is_client = HasBit(p2, 31); + button_mask &= (1U << GOAL_QUESTION_BUTTON_COUNT) - 1; if (_current_company != OWNER_DEITY) return CMD_ERROR; if (text.empty()) return CMD_ERROR; @@ -284,31 +264,28 @@ CommandCost CmdGoalQuestion(DoCommandFlag flags, TileIndex tile, uint32 p1, uint /** * Reply to a goal question. * @param flags type of operation - * @param tile unused. - * @param p1 Unique ID to use for this question. - * @param p2 Button the company pressed - * @param text Text of the question. + * @param uniqueid Unique ID to use for this question. + * @param button Button the company pressed * @return the cost of this operation or an error */ -CommandCost CmdGoalQuestionAnswer(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdGoalQuestionAnswer(DoCommandFlag flags, uint16 uniqueid, uint8 button) { - if (p1 > UINT16_MAX) return CMD_ERROR; - if (p2 >= GOAL_QUESTION_BUTTON_COUNT) return CMD_ERROR; + if (button >= GOAL_QUESTION_BUTTON_COUNT) return CMD_ERROR; if (_current_company == OWNER_DEITY) { /* It has been requested to close this specific question on all clients */ - if (flags & DC_EXEC) CloseWindowById(WC_GOAL_QUESTION, p1); + if (flags & DC_EXEC) CloseWindowById(WC_GOAL_QUESTION, uniqueid); return CommandCost(); } if (_networking && _local_company == _current_company) { /* Somebody in the same company answered the question. Close the window */ - if (flags & DC_EXEC) CloseWindowById(WC_GOAL_QUESTION, p1); + if (flags & DC_EXEC) CloseWindowById(WC_GOAL_QUESTION, uniqueid); if (!_network_server) return CommandCost(); } if (flags & DC_EXEC) { - Game::NewEvent(new ScriptEventGoalQuestionAnswer(p1, (ScriptCompany::CompanyID)(byte)_current_company, (ScriptGoal::QuestionButton)(1 << p2))); + Game::NewEvent(new ScriptEventGoalQuestionAnswer(uniqueid, (ScriptCompany::CompanyID)(byte)_current_company, (ScriptGoal::QuestionButton)(1 << button))); } return CommandCost(); diff --git a/src/goal_cmd.h b/src/goal_cmd.h index 3b047f11ac..5c3e4954f8 100644 --- a/src/goal_cmd.h +++ b/src/goal_cmd.h @@ -11,14 +11,16 @@ #define GOAL_CMD_H #include "command_type.h" +#include "command_type.h" +#include "goal_type.h" -CommandProc CmdCreateGoal; -CommandProc CmdRemoveGoal; -CommandProc CmdSetGoalText; -CommandProc CmdSetGoalProgress; -CommandProc CmdSetGoalCompleted; -CommandProc CmdGoalQuestion; -CommandProc CmdGoalQuestionAnswer; +CommandCost CmdCreateGoal(DoCommandFlag flags, CompanyID company, GoalType type, GoalTypeID dest, const std::string &text); +CommandCost CmdRemoveGoal(DoCommandFlag flags, GoalID goal); +CommandCost CmdSetGoalText(DoCommandFlag flags, GoalID goal, const std::string &text); +CommandCost CmdSetGoalProgress(DoCommandFlag flags, GoalID goal, const std::string &text); +CommandCost CmdSetGoalCompleted(DoCommandFlag flags, GoalID goal, bool completed); +CommandCost CmdGoalQuestion(DoCommandFlag flags, uint16 uniqueid, uint16 target, bool is_client, uint32 button_mask, GoalQuestionType type, const std::string &text); +CommandCost CmdGoalQuestionAnswer(DoCommandFlag flags, uint16 uniqueid, uint8 button); DEF_CMD_TRAIT(CMD_CREATE_GOAL, CmdCreateGoal, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) DEF_CMD_TRAIT(CMD_REMOVE_GOAL, CmdRemoveGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT) diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index ef63197d54..639901ee5b 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -383,17 +383,17 @@ struct GoalQuestionWindow : public Window { { switch (widget) { case WID_GQ_BUTTON_1: - Command::Post(0, this->window_number, this->button[0], {}); + Command::Post(this->window_number, this->button[0]); this->Close(); break; case WID_GQ_BUTTON_2: - Command::Post(0, this->window_number, this->button[1], {}); + Command::Post(this->window_number, this->button[1]); this->Close(); break; case WID_GQ_BUTTON_3: - Command::Post(0, this->window_number, this->button[2], {}); + Command::Post(this->window_number, this->button[2]); this->Close(); break; } diff --git a/src/script/api/script_goal.cpp b/src/script/api/script_goal.cpp index dbc2c51e01..70f040dd45 100644 --- a/src/script/api/script_goal.cpp +++ b/src/script/api/script_goal.cpp @@ -38,7 +38,7 @@ EnforcePreconditionEncodedText(GOAL_INVALID, text); EnforcePrecondition(GOAL_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); - uint8 c = company; + CompanyID c = (::CompanyID)company; if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; StoryPage *story_page = nullptr; if (type == GT_STORY_PAGE && ScriptStoryPage::IsValidStoryPage((ScriptStoryPage::StoryPageID)destination)) story_page = ::StoryPage::Get((ScriptStoryPage::StoryPageID)destination); @@ -50,7 +50,7 @@ (type == GT_COMPANY && ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)destination) != ScriptCompany::COMPANY_INVALID) || (type == GT_STORY_PAGE && story_page != nullptr && (c == INVALID_COMPANY ? story_page->company == INVALID_COMPANY : story_page->company == INVALID_COMPANY || story_page->company == c))); - if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnGoalID, 0, type | (c << 8), destination, text)) return GOAL_INVALID; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnGoalID, c, (::GoalType)type, destination, text)) return GOAL_INVALID; /* In case of test-mode, we return GoalID 0 */ return (ScriptGoal::GoalID)0; @@ -61,7 +61,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); EnforcePrecondition(false, IsValidGoal(goal_id)); - return ScriptObject::Command::Do(0, goal_id, 0, {}); + return ScriptObject::Command::Do(goal_id); } /* static */ bool ScriptGoal::SetText(GoalID goal_id, Text *goal) @@ -73,7 +73,7 @@ EnforcePrecondition(false, goal != nullptr); EnforcePrecondition(false, !StrEmpty(goal->GetEncodedText())); - return ScriptObject::Command::Do(0, goal_id, 0, goal->GetEncodedText()); + return ScriptObject::Command::Do(goal_id, goal->GetEncodedText()); } /* static */ bool ScriptGoal::SetProgress(GoalID goal_id, Text *progress) @@ -88,7 +88,7 @@ progress = nullptr; } - return ScriptObject::Command::Do(0, goal_id, 0, progress != nullptr ? std::string{ progress->GetEncodedText() } : std::string{}); + return ScriptObject::Command::Do(goal_id, progress != nullptr ? std::string{ progress->GetEncodedText() } : std::string{}); } /* static */ bool ScriptGoal::SetCompleted(GoalID goal_id, bool completed) @@ -96,7 +96,7 @@ EnforcePrecondition(false, IsValidGoal(goal_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::Command::Do(0, goal_id, completed ? 1 : 0, {}); + return ScriptObject::Command::Do(goal_id, completed); } /* static */ bool ScriptGoal::IsCompleted(GoalID goal_id) @@ -121,7 +121,7 @@ EnforcePrecondition(false, buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT)); EnforcePrecondition(false, (int)type < ::GQT_END); - return ScriptObject::Command::Do(0, uniqueid | (target << 16), buttons | (type << 29) | (is_client ? (1 << 31) : 0), text); + return ScriptObject::Command::Do(uniqueid, target, is_client, buttons, (::GoalQuestionType)type, text); } /* static */ bool ScriptGoal::Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons) @@ -146,5 +146,5 @@ { EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::Command::Do(0, uniqueid, 0, {}); + return ScriptObject::Command::Do(uniqueid, 0); } diff --git a/src/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp index afa2590414..f767472e02 100644 --- a/src/script/api/script_story_page.cpp +++ b/src/script/api/script_story_page.cpp @@ -49,10 +49,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnStoryPageID, - 0, - c, - 0, - title != nullptr ? std::string{ title->GetEncodedText() } : std::string{})) return STORY_PAGE_INVALID; + (::CompanyID)c, title != nullptr ? std::string{ title->GetEncodedText() } : std::string{})) return STORY_PAGE_INVALID; /* In case of test-mode, we return StoryPageID 0 */ return (ScriptStoryPage::StoryPageID)0; @@ -91,7 +88,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnStoryPageElementID, reftile, - story_page_id + (type << 16), + (::StoryPageID)story_page_id, (::StoryPageElementType)type, refid, StoryPageElementTypeRequiresText(btype) ? std::string{ text->GetEncodedText() } : std::string{})) return STORY_PAGE_ELEMENT_INVALID; @@ -160,7 +157,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, IsValidStoryPage(story_page_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::Command::Do(0, story_page_id, 0, title != nullptr ? std::string{ title->GetEncodedText() } : std::string{}); + return ScriptObject::Command::Do(story_page_id, title != nullptr ? std::string{ title->GetEncodedText() } : std::string{}); } /* static */ ScriptCompany::CompanyID ScriptStoryPage::GetCompany(StoryPageID story_page_id) @@ -186,7 +183,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, IsValidStoryPage(story_page_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::Command::Do(0, story_page_id, date, {}); + return ScriptObject::Command::Do(story_page_id, date); } @@ -195,7 +192,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, IsValidStoryPage(story_page_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::Command::Do(0, story_page_id, 0, {}); + return ScriptObject::Command::Do(story_page_id); } /* static */ bool ScriptStoryPage::Remove(StoryPageID story_page_id) @@ -203,7 +200,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); EnforcePrecondition(false, IsValidStoryPage(story_page_id)); - return ScriptObject::Command::Do(0, story_page_id, 0, {}); + return ScriptObject::Command::Do(story_page_id); } /* static */ bool ScriptStoryPage::RemoveElement(StoryPageElementID story_page_element_id) @@ -211,7 +208,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); EnforcePrecondition(false, IsValidStoryPageElement(story_page_element_id)); - return ScriptObject::Command::Do(0, story_page_element_id, 0, {}); + return ScriptObject::Command::Do(story_page_element_id); } /* static */ ScriptStoryPage::StoryPageButtonFormatting ScriptStoryPage::MakePushButtonReference(StoryPageButtonColour colour, StoryPageButtonFlags flags) diff --git a/src/story.cpp b/src/story.cpp index 24b09ade5d..259bfbd615 100644 --- a/src/story.cpp +++ b/src/story.cpp @@ -198,19 +198,14 @@ bool StoryPageButtonData::ValidateVehicleType() const /** * Create a new story page. * @param flags type of operation - * @param tile unused. - * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 7) - Company for which this story page belongs to. - * @param p2 unused. + * @param company Company for which this story page belongs to. * @param text Title of the story page. Null is allowed in which case a generic page title is provided by OpenTTD. * @return the cost of this operation or an error */ -CommandCost CmdCreateStoryPage(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateStoryPage(DoCommandFlag flags, CompanyID company, const std::string &text) { if (!StoryPage::CanAllocateItem()) return CMD_ERROR; - CompanyID company = (CompanyID)GB(p1, 0, 8); - if (_current_company != OWNER_DEITY) return CMD_ERROR; if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR; @@ -244,20 +239,16 @@ CommandCost CmdCreateStoryPage(DoCommandFlag flags, TileIndex tile, uint32 p1, u * Create a new story page element. * @param flags type of operation * @param tile Tile location if it is a location page element, otherwise unused. - * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 15) - The page which the element belongs to. - * (bit 16 - 23) - Page element type - * @param p2 Id of referenced object + * @param page_id The page which the element belongs to. + * @param type Page element type + * @param reference Id of referenced object * @param text Text content in case it is a text or location page element * @return the cost of this operation or an error */ -CommandCost CmdCreateStoryPageElement(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateStoryPageElement(DoCommandFlag flags, TileIndex tile, StoryPageID page_id, StoryPageElementType type, uint32 reference, const std::string &text) { if (!StoryPageElement::CanAllocateItem()) return CMD_ERROR; - StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); - StoryPageElementType type = Extract(p1); - /* Allow at most 128 elements per page. */ uint16 element_count = 0; for (StoryPageElement *iter : StoryPageElement::Iterate()) { @@ -267,7 +258,7 @@ CommandCost CmdCreateStoryPageElement(DoCommandFlag flags, TileIndex tile, uint3 if (_current_company != OWNER_DEITY) return CMD_ERROR; if (!StoryPage::IsValidID(page_id)) return CMD_ERROR; - if (!VerifyElementContentParameters(page_id, type, tile, p2, text.c_str())) return CMD_ERROR; + if (!VerifyElementContentParameters(page_id, type, tile, reference, text.c_str())) return CMD_ERROR; if (flags & DC_EXEC) { if (_story_page_element_pool.items == 0) { @@ -279,7 +270,7 @@ CommandCost CmdCreateStoryPageElement(DoCommandFlag flags, TileIndex tile, uint3 pe->sort_value = _story_page_element_next_sort_value; pe->type = type; pe->page = page_id; - UpdateElement(*pe, tile, p2, text.c_str()); + UpdateElement(*pe, tile, reference, text.c_str()); InvalidateWindowClassesData(WC_STORY_BOOK, page_id); @@ -294,17 +285,13 @@ CommandCost CmdCreateStoryPageElement(DoCommandFlag flags, TileIndex tile, uint3 * Update a new story page element. * @param flags type of operation * @param tile Tile location if it is a location page element, otherwise unused. - * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 15) - The page element to update. - * (bit 16 - 31) - unused - * @param p2 Id of referenced object + * @param page_element_id The page element to update. + * @param reference Id of referenced object * @param text Text content in case it is a text or location page element * @return the cost of this operation or an error */ -CommandCost CmdUpdateStoryPageElement(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdUpdateStoryPageElement(DoCommandFlag flags, TileIndex tile, StoryPageElementID page_element_id, uint32 reference, const std::string &text) { - StoryPageElementID page_element_id = (StoryPageElementID)GB(p1, 0, 16); - if (_current_company != OWNER_DEITY) return CMD_ERROR; if (!StoryPageElement::IsValidID(page_element_id)) return CMD_ERROR; @@ -312,10 +299,10 @@ CommandCost CmdUpdateStoryPageElement(DoCommandFlag flags, TileIndex tile, uint3 StoryPageID page_id = pe->page; StoryPageElementType type = pe->type; - if (!VerifyElementContentParameters(page_id, type, tile, p2, text.c_str())) return CMD_ERROR; + if (!VerifyElementContentParameters(page_id, type, tile, reference, text.c_str())) return CMD_ERROR; if (flags & DC_EXEC) { - UpdateElement(*pe, tile, p2, text.c_str()); + UpdateElement(*pe, tile, reference, text.c_str()); InvalidateWindowClassesData(WC_STORY_BOOK, pe->page); } @@ -325,16 +312,13 @@ CommandCost CmdUpdateStoryPageElement(DoCommandFlag flags, TileIndex tile, uint3 /** * Update title of a story page. * @param flags type of operation - * @param tile unused. - * @param p1 = (bit 0 - 15) - StoryPageID to update. - * @param p2 unused + * @param page_id StoryPageID to update. * @param text title text of the story page. * @return the cost of this operation or an error */ -CommandCost CmdSetStoryPageTitle(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetStoryPageTitle(DoCommandFlag flags, StoryPageID page_id, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); if (!StoryPage::IsValidID(page_id)) return CMD_ERROR; if (flags & DC_EXEC) { @@ -355,18 +339,14 @@ CommandCost CmdSetStoryPageTitle(DoCommandFlag flags, TileIndex tile, uint32 p1, /** * Update date of a story page. * @param flags type of operation - * @param tile unused. - * @param p1 = (bit 0 - 15) - StoryPageID to update. - * @param p2 = (bit 0 - 31) - date - * @param text unused + * @param page_id StoryPageID to update. + * @param date date * @return the cost of this operation or an error */ -CommandCost CmdSetStoryPageDate(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetStoryPageDate(DoCommandFlag flags, StoryPageID page_id, Date date) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); if (!StoryPage::IsValidID(page_id)) return CMD_ERROR; - Date date = (Date)p2; if (flags & DC_EXEC) { StoryPage *p = StoryPage::Get(page_id); @@ -382,16 +362,12 @@ CommandCost CmdSetStoryPageDate(DoCommandFlag flags, TileIndex tile, uint32 p1, * Display a story page for all clients that are allowed to * view the story page. * @param flags type of operation - * @param tile unused. - * @param p1 = (bit 0 - 15) - StoryPageID to show. - * @param p2 unused - * @param text unused + * @param page_id StoryPageID to show. * @return the cost of this operation or an error */ -CommandCost CmdShowStoryPage(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdShowStoryPage(DoCommandFlag flags, StoryPageID page_id) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); if (!StoryPage::IsValidID(page_id)) return CMD_ERROR; if (flags & DC_EXEC) { @@ -404,16 +380,12 @@ CommandCost CmdShowStoryPage(DoCommandFlag flags, TileIndex tile, uint32 p1, uin /** * Remove a story page and associated story page elements. * @param flags type of operation - * @param tile unused. - * @param p1 = (bit 0 - 15) - StoryPageID to remove. - * @param p2 unused. - * @param text unused. + * @param page_id StoryPageID to remove. * @return the cost of this operation or an error */ -CommandCost CmdRemoveStoryPage(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveStoryPage(DoCommandFlag flags, StoryPageID page_id) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - StoryPageID page_id = (StoryPageID)p1; if (!StoryPage::IsValidID(page_id)) return CMD_ERROR; if (flags & DC_EXEC) { @@ -437,16 +409,12 @@ CommandCost CmdRemoveStoryPage(DoCommandFlag flags, TileIndex tile, uint32 p1, u /** * Remove a story page element * @param flags type of operation - * @param tile unused. - * @param p1 = (bit 0 - 15) - StoryPageElementID to remove. - * @param p2 unused. - * @param text unused. + * @param page_element_id StoryPageElementID to remove. * @return the cost of this operation or an error */ -CommandCost CmdRemoveStoryPageElement(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRemoveStoryPageElement(DoCommandFlag flags, StoryPageElementID page_element_id) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - StoryPageElementID page_element_id = (StoryPageElementID)p1; if (!StoryPageElement::IsValidID(page_element_id)) return CMD_ERROR; if (flags & DC_EXEC) { @@ -465,15 +433,12 @@ CommandCost CmdRemoveStoryPageElement(DoCommandFlag flags, TileIndex tile, uint3 * Clicked/used a button on a story page. * @param flags Type of operation. * @param tile Tile selected, for tile selection buttons, otherwise unused. - * @param p1 Bit 0..15 = story page element id of button. - * @param p2 ID of selected item for buttons that select an item (e.g. vehicle), otherwise unused. - * @param text Unused. + * @param page_element_id story page element id of button. + * @param reference ID of selected item for buttons that select an item (e.g. vehicle), otherwise unused. * @return The cost of the operation, or an error. */ -CommandCost CmdStoryPageButton(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdStoryPageButton(DoCommandFlag flags, TileIndex tile, StoryPageElementID page_element_id, VehicleID reference) { - StoryPageElementID page_element_id = (StoryPageElementID)GB(p1, 0, 16); - if (!StoryPageElement::IsValidID(page_element_id)) return CMD_ERROR; const StoryPageElement *const pe = StoryPageElement::Get(page_element_id); @@ -491,8 +456,8 @@ CommandCost CmdStoryPageButton(DoCommandFlag flags, TileIndex tile, uint32 p1, u if (flags & DC_EXEC) Game::NewEvent(new ScriptEventStoryPageTileSelect(_current_company, pe->page, page_element_id, tile)); break; case SPET_BUTTON_VEHICLE: - if (!Vehicle::IsValidID(p2)) return CMD_ERROR; - if (flags & DC_EXEC) Game::NewEvent(new ScriptEventStoryPageVehicleSelect(_current_company, pe->page, page_element_id, (VehicleID)p2)); + if (!Vehicle::IsValidID(reference)) return CMD_ERROR; + if (flags & DC_EXEC) Game::NewEvent(new ScriptEventStoryPageVehicleSelect(_current_company, pe->page, page_element_id, reference)); break; default: /* Invalid page element type, not a button. */ diff --git a/src/story_cmd.h b/src/story_cmd.h index a7323ec6bf..9dbfd412a3 100644 --- a/src/story_cmd.h +++ b/src/story_cmd.h @@ -11,16 +11,20 @@ #define STORY_CMD_H #include "command_type.h" +#include "company_type.h" +#include "date_type.h" +#include "story_type.h" +#include "vehicle_type.h" -CommandProc CmdCreateStoryPage; -CommandProc CmdCreateStoryPageElement; -CommandProc CmdUpdateStoryPageElement; -CommandProc CmdSetStoryPageTitle; -CommandProc CmdSetStoryPageDate; -CommandProc CmdShowStoryPage; -CommandProc CmdRemoveStoryPage; -CommandProc CmdRemoveStoryPageElement; -CommandProc CmdStoryPageButton; +CommandCost CmdCreateStoryPage(DoCommandFlag flags, CompanyID company, const std::string &text); +CommandCost CmdCreateStoryPageElement(DoCommandFlag flags, TileIndex tile, StoryPageID page_id, StoryPageElementType type, uint32 reference, const std::string &text); +CommandCost CmdUpdateStoryPageElement(DoCommandFlag flags, TileIndex tile, StoryPageElementID page_element_id, uint32 reference, const std::string &text); +CommandCost CmdSetStoryPageTitle(DoCommandFlag flags, StoryPageID page_id, const std::string &text); +CommandCost CmdSetStoryPageDate(DoCommandFlag flags, StoryPageID page_id, Date date); +CommandCost CmdShowStoryPage(DoCommandFlag flags, StoryPageID page_id); +CommandCost CmdRemoveStoryPage(DoCommandFlag flags, StoryPageID page_id); +CommandCost CmdRemoveStoryPageElement(DoCommandFlag flags, StoryPageElementID page_element_id); +CommandCost CmdStoryPageButton(DoCommandFlag flags, TileIndex tile, StoryPageElementID page_element_id, VehicleID reference); DEF_CMD_TRAIT(CMD_CREATE_STORY_PAGE, CmdCreateStoryPage, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) DEF_CMD_TRAIT(CMD_CREATE_STORY_PAGE_ELEMENT, CmdCreateStoryPageElement, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 21dba8fd1a..b456b39e9a 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -567,7 +567,7 @@ protected: this->SetTimeout(); this->SetWidgetDirty(WID_SB_PAGE_PANEL); - Command::Post(0, pe.index, 0, {}); + Command::Post(0, pe.index, 0); break; case SPET_BUTTON_TILE: @@ -922,7 +922,7 @@ public: return; } - Command::Post(tile, pe->index, 0, {}); + Command::Post(tile, pe->index, 0); ResetObjectToPlace(); } @@ -941,7 +941,7 @@ public: VehicleType wanted_vehtype = data.GetVehicleType(); if (wanted_vehtype != VEH_INVALID && wanted_vehtype != v->type) return false; - Command::Post(0, pe->index, v->index, {}); + Command::Post(0, pe->index, v->index); ResetObjectToPlace(); return true; } diff --git a/src/story_type.h b/src/story_type.h index 1dce00008b..e919564a7f 100644 --- a/src/story_type.h +++ b/src/story_type.h @@ -16,6 +16,7 @@ typedef uint16 StoryPageElementID; ///< ID of a story page element typedef uint16 StoryPageID; ///< ID of a story page struct StoryPageElement; struct StoryPage; +enum StoryPageElementType : byte; extern StoryPageElementID _new_story_page_element_id; extern StoryPageID _new_story_page_id; From c6d7b98808575f31103121528565ed252a3cfc6c Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 21 Nov 2021 23:02:29 +0100 Subject: [PATCH 31/60] Codechange: Un-bitstuff landscape commands. --- src/clear_cmd.cpp | 2 +- src/disaster_vehicle.cpp | 4 ++-- src/industry_cmd.cpp | 14 +++++------ src/landscape.cpp | 25 ++++++++----------- src/landscape_cmd.h | 4 ++-- src/map_type.h | 2 +- src/misc_gui.cpp | 2 +- src/object_cmd.cpp | 12 +++++----- src/rail_cmd.cpp | 10 ++++---- src/road_cmd.cpp | 12 +++++----- src/script/api/script_airport.cpp | 2 +- src/script/api/script_bridge.cpp | 2 +- src/script/api/script_marine.cpp | 10 ++++---- src/script/api/script_road.cpp | 2 +- src/script/api/script_tile.cpp | 8 +++---- src/script/api/script_tunnel.cpp | 2 +- src/slope_type.h | 2 +- src/station_cmd.cpp | 14 +++++------ src/terraform_cmd.cpp | 40 ++++++++++++++----------------- src/terraform_cmd.h | 6 +++-- src/terraform_gui.cpp | 24 +++++++++---------- src/town_cmd.cpp | 32 ++++++++++++------------- src/tree_cmd.cpp | 4 ++-- src/tunnelbridge_cmd.cpp | 16 ++++++------- src/water_cmd.cpp | 22 ++++++++--------- src/waypoint_cmd.cpp | 2 +- 26 files changed, 134 insertions(+), 141 deletions(-) diff --git a/src/clear_cmd.cpp b/src/clear_cmd.cpp index f2f7ecc197..17711a6267 100644 --- a/src/clear_cmd.cpp +++ b/src/clear_cmd.cpp @@ -382,7 +382,7 @@ static void ChangeTileOwner_Clear(TileIndex tile, Owner old_owner, Owner new_own static CommandCost TerraformTile_Clear(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { - return Command::Do(flags, tile, 0, 0, {}); + return Command::Do(flags, tile); } extern const TileTypeProcs _tile_type_clear_procs = { diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index 6319af0ab2..668a1caea5 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -62,7 +62,7 @@ static void DisasterClearSquare(TileIndex tile) case MP_RAILWAY: if (Company::IsHumanID(GetTileOwner(tile)) && !IsRailDepot(tile)) { Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); - Command::Do(DC_EXEC, tile, 0, 0, {}); + Command::Do(DC_EXEC, tile); cur_company.Restore(); /* update signals in buffer */ @@ -72,7 +72,7 @@ static void DisasterClearSquare(TileIndex tile) case MP_HOUSE: { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); - Command::Do(DC_EXEC, tile, 0, 0, {}); + Command::Do(DC_EXEC, tile); cur_company.Restore(); break; } diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index b7d6d3714c..2c45a84729 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1103,7 +1103,7 @@ static bool SearchLumberMillTrees(TileIndex tile, void *user_data) _industry_sound_tile = tile; if (_settings_client.sound.ambient) SndPlayTileFx(SND_38_LUMBER_MILL_1, tile); - Command::Do(DC_EXEC, tile, 0, 0, {}); + Command::Do(DC_EXEC, tile); cur_company.Restore(); return true; @@ -1485,13 +1485,13 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */ Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); - CommandCost ret = Command::Do(DC_NONE, cur_tile, 0, 0, {}); + CommandCost ret = Command::Do(DC_NONE, cur_tile); cur_company.Restore(); if (ret.Failed()) return ret; } else { /* Clear the tiles, but do not affect town ratings */ - CommandCost ret = Command::Do(DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, cur_tile, 0, 0, {}); + CommandCost ret = Command::Do(DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, cur_tile); if (ret.Failed()) return ret; } @@ -1601,7 +1601,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, } /* This is not 100% correct check, but the best we can do without modifying the map. * What is missing, is if the difference in height is more than 1.. */ - if (Command::Do(flags & ~DC_EXEC, tile_walk, SLOPE_N, (curh > h) ? 0 : 1, {}).Failed()) { + if (Command::Do(flags & ~DC_EXEC, tile_walk, SLOPE_N, curh <= h).Failed()) { cur_company.Restore(); return false; } @@ -1616,7 +1616,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, /* We give the terraforming for free here, because we can't calculate * exact cost in the test-round, and as we all know, that will cause * a nice assert if they don't match ;) */ - Command::Do(flags, tile_walk, SLOPE_N, (curh > h) ? 0 : 1, {}); + Command::Do(flags, tile_walk, SLOPE_N, curh <= h); curh += (curh > h) ? -1 : 1; } } @@ -1886,7 +1886,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID); - Command::Do(DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, cur_tile, 0, 0, {}); + Command::Do(DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, cur_tile); MakeIndustry(cur_tile, i->index, it.gfx, Random(), wc); @@ -3062,7 +3062,7 @@ static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, i } } } - return Command::Do(flags, tile, 0, 0, {}); + return Command::Do(flags, tile); } extern const TileTypeProcs _tile_type_industry_procs = { diff --git a/src/landscape.cpp b/src/landscape.cpp index 6efa8dba29..43bc238ac9 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -686,12 +686,9 @@ void ClearSnowLine() * Clear a piece of landscape * @param flags of operation to conduct * @param tile tile to clear - * @param p1 unused - * @param p2 unused - * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdLandscapeClear(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdLandscapeClear(DoCommandFlag flags, TileIndex tile) { CommandCost cost(EXPENSES_CONSTRUCTION); bool do_clear = false; @@ -735,15 +732,13 @@ CommandCost CmdLandscapeClear(DoCommandFlag flags, TileIndex tile, uint32 p1, ui * Clear a big piece of landscape * @param flags of operation to conduct * @param tile end tile of area dragging - * @param p1 start tile of area dragging - * @param p2 various bitstuffed data. - * bit 0: Whether to use the Orthogonal (0) or Diagonal (1) iterator. - * @param text unused + * @param start_tile start tile of area dragging + * @param diagonal Whether to use the Orthogonal (false) or Diagonal (true) iterator. * @return the cost of this operation or an error */ -CommandCost CmdClearArea(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdClearArea(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, bool diagonal) { - if (p1 >= MapSize()) return CMD_ERROR; + if (start_tile >= MapSize()) return CMD_ERROR; Money money = GetAvailableMoneyForCommand(); CommandCost cost(EXPENSES_CONSTRUCTION); @@ -753,10 +748,10 @@ CommandCost CmdClearArea(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 const Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? nullptr : Company::GetIfValid(_current_company); int limit = (c == nullptr ? INT32_MAX : GB(c->clear_limit, 16, 16)); - TileIterator *iter = HasBit(p2, 0) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1); + TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(tile, start_tile) : new OrthogonalTileIterator(tile, start_tile); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex t = *iter; - CommandCost ret = Command::Do(flags & ~DC_EXEC, t, 0, 0, {}); + CommandCost ret = Command::Do(flags & ~DC_EXEC, t); if (ret.Failed()) { last_error = ret; @@ -773,14 +768,14 @@ CommandCost CmdClearArea(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 delete iter; return cost; } - Command::Do(flags, t, 0, 0, {}); + Command::Do(flags, t); /* draw explosion animation... * Disable explosions when game is paused. Looks silly and blocks the view. */ - if ((t == tile || t == p1) && _pause_mode == PM_UNPAUSED) { + if ((t == tile || t == start_tile) && _pause_mode == PM_UNPAUSED) { /* big explosion in two corners, or small explosion for single tiles */ CreateEffectVehicleAbove(TileX(t) * TILE_SIZE + TILE_SIZE / 2, TileY(t) * TILE_SIZE + TILE_SIZE / 2, 2, - TileX(tile) == TileX(p1) && TileY(tile) == TileY(p1) ? EV_EXPLOSION_SMALL : EV_EXPLOSION_LARGE + TileX(tile) == TileX(start_tile) && TileY(tile) == TileY(start_tile) ? EV_EXPLOSION_SMALL : EV_EXPLOSION_LARGE ); } } else { diff --git a/src/landscape_cmd.h b/src/landscape_cmd.h index f3b6fd3fca..5af2787231 100644 --- a/src/landscape_cmd.h +++ b/src/landscape_cmd.h @@ -12,8 +12,8 @@ #include "command_type.h" -CommandProc CmdLandscapeClear; -CommandProc CmdClearArea; +CommandCost CmdLandscapeClear(DoCommandFlag flags, TileIndex tile); +CommandCost CmdClearArea(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, bool diagonal); DEF_CMD_TRAIT(CMD_LANDSCAPE_CLEAR, CmdLandscapeClear, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_CLEAR_AREA, CmdClearArea, CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // destroying multi-tile houses makes town rating differ between test and execution diff --git a/src/map_type.h b/src/map_type.h index f34f137c64..f0fae28a6c 100644 --- a/src/map_type.h +++ b/src/map_type.h @@ -78,7 +78,7 @@ static const uint MAX_MAP_SIZE = 1 << MAX_MAP_SIZE_BITS; ///< Maximal map s #define STRAIGHT_TRACK_LENGTH 7071/10000 /** Argument for CmdLevelLand describing what to do. */ -enum LevelMode { +enum LevelMode : byte { LM_LEVEL, ///< Level the land. LM_LOWER, ///< Lower the land. LM_RAISE, ///< Raise the land. diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index b2e8b886e0..bc5179f82f 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -192,7 +192,7 @@ public: Company *c = Company::GetIfValid(_local_company); if (c != nullptr) { assert(_current_company == _local_company); - CommandCost costclear = Command::Do(DC_QUERY_COST, tile, 0, 0, {}); + CommandCost costclear = Command::Do(DC_QUERY_COST, tile); if (costclear.Succeeded()) { Money cost = costclear.GetCost(); if (cost < 0) { diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index a651239baf..9968424e0a 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -231,7 +231,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 if (type == OBJECT_OWNED_LAND) { /* Owned land is special as it can be placed on any slope. */ - cost.AddCost(Command::Do(flags, tile, 0, 0, {})); + cost.AddCost(Command::Do(flags, tile)); } else { /* Check the surface to build on. At this time we can't actually execute the * the CLEAR_TILE commands since the newgrf callback later on can check @@ -244,7 +244,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 if (!IsWaterTile(t)) { /* Normal water tiles don't have to be cleared. For all other tile types clear * the tile but leave the water. */ - cost.AddCost(Command::Do(flags & ~DC_NO_WATER & ~DC_EXEC, t, 0, 0, {})); + cost.AddCost(Command::Do(flags & ~DC_NO_WATER & ~DC_EXEC, t)); } else { /* Can't build on water owned by another company. */ Owner o = GetTileOwner(t); @@ -262,7 +262,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 IsTileType(t, MP_OBJECT) && IsTileOwner(t, _current_company) && IsObjectType(t, OBJECT_HQ))) { - cost.AddCost(Command::Do(flags & ~DC_EXEC, t, 0, 0, {})); + cost.AddCost(Command::Do(flags & ~DC_EXEC, t)); } } } @@ -294,10 +294,10 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint3 for (TileIndex t : ta) { if (HasTileWaterGround(t)) { if (!IsWaterTile(t)) { - Command::Do((flags & ~DC_NO_WATER) | DC_NO_MODIFY_TOWN_RATING, t, 0, 0, {}); + Command::Do((flags & ~DC_NO_WATER) | DC_NO_MODIFY_TOWN_RATING, t); } } else { - Command::Do(flags | DC_NO_MODIFY_TOWN_RATING, t, 0, 0, {}); + Command::Do(flags | DC_NO_MODIFY_TOWN_RATING, t); } } } @@ -849,7 +849,7 @@ static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlag flags, int } } - return Command::Do(flags, tile, 0, 0, {}); + return Command::Do(flags, tile); } extern const TileTypeProcs _tile_type_object_procs = { diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 35c58a1d74..ee36afb039 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -448,7 +448,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType rai CommandCost ret = CheckTileOwnership(tile); if (ret.Failed()) return ret; - if (!IsPlainRail(tile)) return Command::Do(flags, tile, 0, 0, {}); // just get appropriate error message + if (!IsPlainRail(tile)) return Command::Do(flags, tile); // just get appropriate error message if (!IsCompatibleRail(GetRailType(tile), railtype)) return_cmd_error(STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION); @@ -578,7 +578,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType rai if (ret.Failed()) return ret; cost.AddCost(ret); - ret = Command::Do(flags, tile, 0, 0, {}); + ret = Command::Do(flags, tile); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -987,7 +987,7 @@ CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType rai cost.AddCost(_price[PR_BUILD_FOUNDATION]); } - cost.AddCost(Command::Do(flags, tile, 0, 0, {})); + cost.AddCost(Command::Do(flags, tile)); if (cost.Failed()) return cost; if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -2882,7 +2882,7 @@ static void ChangeTileOwner_Track(TileIndex tile, Owner old_owner, Owner new_own SetTileOwner(tile, new_owner); } else { - Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); + Command::Do(DC_EXEC | DC_BANKRUPT, tile); } } @@ -3070,7 +3070,7 @@ static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, int AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) { return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } - return Command::Do(flags, tile, 0, 0, {}); + return Command::Do(flags, tile); } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index e160a2b842..8cf07e8d61 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -369,7 +369,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec if (!IsTileType(tile, MP_ROAD)) { /* If it's the last roadtype, just clear the whole tile */ - if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) return Command::Do(flags, tile, 0, 0, {}); + if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) return Command::Do(flags, tile); CommandCost cost(EXPENSES_CONSTRUCTION); if (IsTileType(tile, MP_TUNNELBRIDGE)) { @@ -817,7 +817,7 @@ do_clear:; } if (need_to_clear) { - CommandCost ret = Command::Do(flags, tile, 0, 0, {}); + CommandCost ret = Command::Do(flags, tile); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -1153,7 +1153,7 @@ CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, RoadType rt, cost.AddCost(_price[PR_BUILD_FOUNDATION]); } - cost.AddCost(Command::Do(flags, tile, 0, 0, {})); + cost.AddCost(Command::Do(flags, tile)); if (cost.Failed()) return cost; if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); @@ -1239,7 +1239,7 @@ static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags) } if (flags & DC_EXEC) { - Command::Do(flags, tile, 0, 0, {}); + Command::Do(flags, tile); } return ret; } @@ -2167,7 +2167,7 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne if (IsRoadDepot(tile)) { if (GetTileOwner(tile) == old_owner) { if (new_owner == INVALID_OWNER) { - Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); + Command::Do(DC_EXEC | DC_BANKRUPT, tile); } else { /* A road depot has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */ RoadType rt = GetRoadTypeRoad(tile); @@ -2253,7 +2253,7 @@ static CommandCost TerraformTile_Road(TileIndex tile, DoCommandFlag flags, int z } } - return Command::Do(flags, tile, 0, 0, {}); + return Command::Do(flags, tile); } /** Update power of road vehicle under which is the roadtype being converted */ diff --git a/src/script/api/script_airport.cpp b/src/script/api/script_airport.cpp index 8ed4dbfcac..4416a4bcda 100644 --- a/src/script/api/script_airport.cpp +++ b/src/script/api/script_airport.cpp @@ -86,7 +86,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)) EnforcePrecondition(false, IsAirportTile(tile) || IsHangarTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ int32 ScriptAirport::GetNumHangars(TileIndex tile) diff --git a/src/script/api/script_bridge.cpp b/src/script/api/script_bridge.cpp index fbea9fb127..b0fda24128 100644 --- a/src/script/api/script_bridge.cpp +++ b/src/script/api/script_bridge.cpp @@ -121,7 +121,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) { EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsBridgeTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ char *ScriptBridge::GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type) diff --git a/src/script/api/script_marine.cpp b/src/script/api/script_marine.cpp index 059157e276..ba5163e49e 100644 --- a/src/script/api/script_marine.cpp +++ b/src/script/api/script_marine.cpp @@ -125,7 +125,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsWaterDepotTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ bool ScriptMarine::RemoveDock(TileIndex tile) @@ -134,7 +134,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsDockTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ bool ScriptMarine::RemoveBuoy(TileIndex tile) @@ -143,7 +143,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsBuoyTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ bool ScriptMarine::RemoveLock(TileIndex tile) @@ -152,7 +152,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsLockTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ bool ScriptMarine::RemoveCanal(TileIndex tile) @@ -161,7 +161,7 @@ EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsCanalTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ Money ScriptMarine::GetBuildCost(BuildType build_type) diff --git a/src/script/api/script_road.cpp b/src/script/api/script_road.cpp index 297a8f56c1..cae144a871 100644 --- a/src/script/api/script_road.cpp +++ b/src/script/api/script_road.cpp @@ -593,7 +593,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, IsTileType(tile, MP_ROAD)) EnforcePrecondition(false, GetRoadTileType(tile) == ROAD_TILE_DEPOT); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ bool ScriptRoad::RemoveRoadStation(TileIndex tile) diff --git a/src/script/api/script_tile.cpp b/src/script/api/script_tile.cpp index 9e67b074a2..8be74c0304 100644 --- a/src/script/api/script_tile.cpp +++ b/src/script/api/script_tile.cpp @@ -255,7 +255,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, tile < ::MapSize()); - return ScriptObject::Command::Do(tile, slope, 1, {}); + return ScriptObject::Command::Do(tile, (::Slope)slope, true); } /* static */ bool ScriptTile::LowerTile(TileIndex tile, int32 slope) @@ -263,7 +263,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, tile < ::MapSize()); - return ScriptObject::Command::Do(tile, slope, 0, {}); + return ScriptObject::Command::Do(tile, (::Slope)slope, false); } /* static */ bool ScriptTile::LevelTiles(TileIndex start_tile, TileIndex end_tile) @@ -272,14 +272,14 @@ EnforcePrecondition(false, start_tile < ::MapSize()); EnforcePrecondition(false, end_tile < ::MapSize()); - return ScriptObject::Command::Do(end_tile, start_tile, LM_LEVEL << 1, {}); + return ScriptObject::Command::Do(end_tile, start_tile, false, LM_LEVEL); } /* static */ bool ScriptTile::DemolishTile(TileIndex tile) { EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } /* static */ bool ScriptTile::PlantTree(TileIndex tile) diff --git a/src/script/api/script_tunnel.cpp b/src/script/api/script_tunnel.cpp index 8529f908db..04c182c1fb 100644 --- a/src/script/api/script_tunnel.cpp +++ b/src/script/api/script_tunnel.cpp @@ -126,5 +126,5 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsTunnelTile(tile)); - return ScriptObject::Command::Do(tile, 0, 0, {}); + return ScriptObject::Command::Do(tile); } diff --git a/src/slope_type.h b/src/slope_type.h index a2c51bd19e..ea2ed1aca5 100644 --- a/src/slope_type.h +++ b/src/slope_type.h @@ -45,7 +45,7 @@ enum Corner { * slopes would mean that it is not a steep slope as halftile * slopes only span one height level. */ -enum Slope { +enum Slope : byte { SLOPE_FLAT = 0x00, ///< a flat tile SLOPE_W = 0x01, ///< the west corner of the tile is raised SLOPE_S = 0x02, ///< the south corner of the tile is raised diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 6424a73e15..b0603485df 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -845,7 +845,7 @@ static CommandCost CheckFlatLandAirport(AirportTileTableIterator tile_iter, DoCo if (ret.Failed()) return ret; cost.AddCost(ret); - ret = Command::Do(flags, tile_iter, 0, 0, {}); + ret = Command::Do(flags, tile_iter); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -932,7 +932,7 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl continue; } } - ret = Command::Do(flags, tile_cur, 0, 0, {}); + ret = Command::Do(flags, tile_cur); if (ret.Failed()) return ret; cost.AddCost(ret); } @@ -1050,7 +1050,7 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags cost.AddCost(RoadBuildCost(rt) * 2); } } else { - ret = Command::Do(flags, cur_tile, 0, 0, {}); + ret = Command::Do(flags, cur_tile); if (ret.Failed()) return ret; cost.AddCost(ret); cost.AddCost(RoadBuildCost(rt) * 2); @@ -2489,7 +2489,7 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_ if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_STATION_DOCK]); - ret = Command::Do(flags, tile, 0, 0, {}); + ret = Command::Do(flags, tile); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -2504,7 +2504,7 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_ /* Get the water class of the water tile before it is cleared.*/ WaterClass wc = GetWaterClass(tile_cur); - ret = Command::Do(flags, tile_cur, 0, 0, {}); + ret = Command::Do(flags, tile_cur); if (ret.Failed()) return ret; tile_cur += TileOffsByDiagDir(direction); @@ -4197,7 +4197,7 @@ static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_o /* Change owner of tile and all roadtypes */ ChangeTileOwner(tile, old_owner, new_owner); } else { - Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); + Command::Do(DC_EXEC | DC_BANKRUPT, tile); /* Set tile owner of water under (now removed) buoy and dock to OWNER_NONE. * Update owner of buoy if it was not removed (was in orders). * Do not update when owned by OWNER_WATER (sea and rivers). */ @@ -4314,7 +4314,7 @@ static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, in } } } - return Command::Do(flags, tile, 0, 0, {}); + return Command::Do(flags, tile); } /** diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index df178e3abf..e4f6b141a9 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -182,42 +182,41 @@ static CommandCost TerraformTileHeight(TerraformerState *ts, TileIndex tile, int * Terraform land * @param flags for this command type * @param tile tile to terraform - * @param p1 corners to terraform (SLOPE_xxx) - * @param p2 direction; eg up (non-zero) or down (zero) - * @param text unused + * @param slope corners to terraform (SLOPE_xxx) + * @param dir_up direction; eg up (true) or down (false) * @return the cost of this operation or an error */ -CommandCost CmdTerraformLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdTerraformLand(DoCommandFlag flags, TileIndex tile, Slope slope, bool dir_up) { _terraform_err_tile = INVALID_TILE; CommandCost total_cost(EXPENSES_CONSTRUCTION); - int direction = (p2 != 0 ? 1 : -1); + int direction = (dir_up ? 1 : -1); TerraformerState ts; /* Compute the costs and the terraforming result in a model of the landscape */ - if ((p1 & SLOPE_W) != 0 && tile + TileDiffXY(1, 0) < MapSize()) { + if ((slope & SLOPE_W) != 0 && tile + TileDiffXY(1, 0) < MapSize()) { TileIndex t = tile + TileDiffXY(1, 0); CommandCost cost = TerraformTileHeight(&ts, t, TileHeight(t) + direction); if (cost.Failed()) return cost; total_cost.AddCost(cost); } - if ((p1 & SLOPE_S) != 0 && tile + TileDiffXY(1, 1) < MapSize()) { + if ((slope & SLOPE_S) != 0 && tile + TileDiffXY(1, 1) < MapSize()) { TileIndex t = tile + TileDiffXY(1, 1); CommandCost cost = TerraformTileHeight(&ts, t, TileHeight(t) + direction); if (cost.Failed()) return cost; total_cost.AddCost(cost); } - if ((p1 & SLOPE_E) != 0 && tile + TileDiffXY(0, 1) < MapSize()) { + if ((slope & SLOPE_E) != 0 && tile + TileDiffXY(0, 1) < MapSize()) { TileIndex t = tile + TileDiffXY(0, 1); CommandCost cost = TerraformTileHeight(&ts, t, TileHeight(t) + direction); if (cost.Failed()) return cost; total_cost.AddCost(cost); } - if ((p1 & SLOPE_N) != 0) { + if ((slope & SLOPE_N) != 0) { TileIndex t = tile + TileDiffXY(0, 0); CommandCost cost = TerraformTileHeight(&ts, t, TileHeight(t) + direction); if (cost.Failed()) return cost; @@ -291,7 +290,7 @@ CommandCost CmdTerraformLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uin } CommandCost cost; if (indirectly_cleared) { - cost = Command::Do(tile_flags, t, 0, 0, {}); + cost = Command::Do(tile_flags, t); } else { cost = _tile_type_procs[GetTileType(t)]->terraform_tile_proc(t, tile_flags, z_min, tileh); } @@ -337,25 +336,22 @@ CommandCost CmdTerraformLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uin * Levels a selected (rectangle) area of land * @param flags for this command type * @param tile end tile of area-drag - * @param p1 start tile of area drag - * @param p2 various bitstuffed data. - * bit 0: Whether to use the Orthogonal (0) or Diagonal (1) iterator. - * bits 1 - 2: Mode of leveling \c LevelMode. - * @param text unused + * @param start_tile start tile of area drag + * @param diagonal Whether to use the Orthogonal (false) or Diagonal (true) iterator. + * @param LevelMode Mode of leveling \c LevelMode. * @return the cost of this operation or an error */ -CommandCost CmdLevelLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdLevelLand(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, bool diagonal, LevelMode lm) { - if (p1 >= MapSize()) return CMD_ERROR; + if (start_tile >= MapSize()) return CMD_ERROR; _terraform_err_tile = INVALID_TILE; /* remember level height */ - uint oldh = TileHeight(p1); + uint oldh = TileHeight(start_tile); /* compute new height */ uint h = oldh; - LevelMode lm = (LevelMode)GB(p2, 1, 2); switch (lm) { case LM_LEVEL: break; case LM_RAISE: h++; break; @@ -375,12 +371,12 @@ CommandCost CmdLevelLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 int limit = (c == nullptr ? INT32_MAX : GB(c->terraform_limit, 16, 16)); if (limit == 0) return_cmd_error(STR_ERROR_TERRAFORM_LIMIT_REACHED); - TileIterator *iter = HasBit(p2, 0) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1); + TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(tile, start_tile) : new OrthogonalTileIterator(tile, start_tile); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex t = *iter; uint curh = TileHeight(t); while (curh != h) { - CommandCost ret = Command::Do(flags & ~DC_EXEC, t, SLOPE_N, (curh > h) ? 0 : 1, {}); + CommandCost ret = Command::Do(flags & ~DC_EXEC, t, SLOPE_N, curh <= h); if (ret.Failed()) { last_error = ret; @@ -396,7 +392,7 @@ CommandCost CmdLevelLand(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 delete iter; return cost; } - Command::Do(flags, t, SLOPE_N, (curh > h) ? 0 : 1, {}); + Command::Do(flags, t, SLOPE_N, curh <= h); } else { /* When we're at the terraform limit we better bail (unneeded) testing as well. * This will probably cause the terraforming cost to be underestimated, but only diff --git a/src/terraform_cmd.h b/src/terraform_cmd.h index 9b5866efaf..861e0d9949 100644 --- a/src/terraform_cmd.h +++ b/src/terraform_cmd.h @@ -11,9 +11,11 @@ #define TERRAFORM_CMD_H #include "command_type.h" +#include "map_type.h" +#include "slope_type.h" -CommandProc CmdTerraformLand; -CommandProc CmdLevelLand; +CommandCost CmdTerraformLand(DoCommandFlag flags, TileIndex tile, Slope slope, bool dir_up); +CommandCost CmdLevelLand(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, bool diagonal, LevelMode lm); DEF_CMD_TRAIT(CMD_TERRAFORM_LAND, CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_LEVEL_LAND, CmdLevelLand, CMD_ALL_TILES | CMD_AUTO | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // test run might clear tiles multiple times, in execution that only happens once diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 7399d6ffa2..c12f10dedc 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -65,7 +65,7 @@ static void GenerateDesertArea(TileIndex end, TileIndex start) TileArea ta(start, end); for (TileIndex tile : ta) { SetTropicZone(tile, (_ctrl_pressed) ? TROPICZONE_NORMAL : TROPICZONE_DESERT); - Command::Post(tile, 0, 0, {}); + Command::Post(tile); MarkTileDirtyByTile(tile); } old_generating_world.Restore(); @@ -120,16 +120,16 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t switch (proc) { case DDSP_DEMOLISH_AREA: - Command::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed ? 1 : 0, {}); + Command::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed); break; case DDSP_RAISE_AND_LEVEL_AREA: - Command::Post(STR_ERROR_CAN_T_RAISE_LAND_HERE, CcTerraform, end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0), {}); + Command::Post(STR_ERROR_CAN_T_RAISE_LAND_HERE, CcTerraform, end_tile, start_tile, _ctrl_pressed, LM_RAISE); break; case DDSP_LOWER_AND_LEVEL_AREA: - Command::Post(STR_ERROR_CAN_T_LOWER_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LOWER << 1 | (_ctrl_pressed ? 1 : 0), {}); + Command::Post(STR_ERROR_CAN_T_LOWER_LAND_HERE, CcTerraform, end_tile, start_tile, _ctrl_pressed, LM_LOWER); break; case DDSP_LEVEL_AREA: - Command::Post(STR_ERROR_CAN_T_LEVEL_LAND_HERE, CcTerraform, end_tile, start_tile, LM_LEVEL << 1 | (_ctrl_pressed ? 1 : 0), {}); + Command::Post(STR_ERROR_CAN_T_LEVEL_LAND_HERE, CcTerraform, end_tile, start_tile, _ctrl_pressed, LM_LEVEL); break; case DDSP_CREATE_ROCKS: GenerateRockyArea(end_tile, start_tile); @@ -392,15 +392,15 @@ static byte _terraform_size = 1; * @todo : Incorporate into game itself to allow for ingame raising/lowering of * larger chunks at the same time OR remove altogether, as we have 'level land' ? * @param tile The top-left tile where the terraforming will start - * @param mode 1 for raising, 0 for lowering land + * @param mode true for raising, false for lowering land */ -static void CommonRaiseLowerBigLand(TileIndex tile, int mode) +static void CommonRaiseLowerBigLand(TileIndex tile, bool mode) { if (_terraform_size == 1) { StringID msg = mode ? STR_ERROR_CAN_T_RAISE_LAND_HERE : STR_ERROR_CAN_T_LOWER_LAND_HERE; - Command::Post(msg, CcTerraform, tile, SLOPE_N, (uint32)mode, {}); + Command::Post(msg, CcTerraform, tile, SLOPE_N, mode); } else { assert(_terraform_size != 0); TileArea ta(tile, _terraform_size, _terraform_size); @@ -427,7 +427,7 @@ static void CommonRaiseLowerBigLand(TileIndex tile, int mode) for (TileIndex tile2 : ta) { if (TileHeight(tile2) == h) { - Command::Post(tile2, SLOPE_N, (uint32)mode, {}); + Command::Post(tile2, SLOPE_N, mode); } } } @@ -516,7 +516,7 @@ static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed) /* Delete all station signs */ for (BaseStation *st : BaseStation::Iterate()) { /* There can be buoys, remove them */ - if (IsBuoyTile(st->xy)) Command::Do(DC_EXEC | DC_BANKRUPT, st->xy, 0, 0, {}); + if (IsBuoyTile(st->xy)) Command::Do(DC_EXEC | DC_BANKRUPT, st->xy); if (!st->IsInUse()) delete st; } @@ -659,11 +659,11 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { break; case WID_ETT_LOWER_LAND: // Lower land button - CommonRaiseLowerBigLand(tile, 0); + CommonRaiseLowerBigLand(tile, false); break; case WID_ETT_RAISE_LAND: // Raise land button - CommonRaiseLowerBigLand(tile, 1); + CommonRaiseLowerBigLand(tile, true); break; case WID_ETT_LEVEL_LAND: // Level land button diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 7ef07aa6aa..ea5a81eb7b 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -944,7 +944,7 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) * This is to make sure that we can build a road here later. */ RoadType rt = GetTownRoadType(t); if (Command::Do(DC_AUTO | DC_NO_WATER, tile, (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X, rt, DRD_NONE, 0).Failed() && - Command::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Failed()) { + Command::Do(DC_AUTO | DC_NO_WATER, tile).Failed()) { return false; } } @@ -962,7 +962,7 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) if (!_generating_world && Chance16(1, 10)) { /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */ res = Command::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, - tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, 0, {}); + tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false); } if (res.Failed() && Chance16(1, 3)) { /* We can consider building on the slope, though. */ @@ -974,13 +974,13 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) return ret; } -static bool TerraformTownTile(TileIndex tile, int edges, int dir) +static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir) { assert(tile < MapSize()); - CommandCost r = Command::Do(DC_AUTO | DC_NO_WATER, tile, edges, dir, {}); + CommandCost r = Command::Do(DC_AUTO | DC_NO_WATER, tile, edges, dir); if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false; - Command::Do(DC_AUTO | DC_NO_WATER | DC_EXEC, tile, edges, dir, {}); + Command::Do(DC_AUTO | DC_NO_WATER | DC_EXEC, tile, edges, dir); return true; } @@ -994,8 +994,8 @@ static void LevelTownLand(TileIndex tile) if (tileh == SLOPE_FLAT) return; /* First try up, then down */ - if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, 1)) { - TerraformTownTile(tile, tileh & SLOPE_ELEVATED, 0); + if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) { + TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false); } } @@ -1737,7 +1737,7 @@ static bool GrowTown(Town *t) for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { /* Only work with plain land that not already has a house */ if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) { - if (Command::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Succeeded()) { + if (Command::Do(DC_AUTO | DC_NO_WATER, tile).Succeeded()) { RoadType rt = GetTownRoadType(t); Command::Do(DC_EXEC | DC_AUTO, tile, GenRandomRoadBits(), rt, DRD_NONE, t->index); cur_company.Restore(); @@ -2280,7 +2280,7 @@ HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile) */ static inline void ClearMakeHouseTile(TileIndex tile, Town *t, byte counter, byte stage, HouseID type, byte random_bits) { - [[maybe_unused]] CommandCost cc = Command::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile, 0, 0, {}); + [[maybe_unused]] CommandCost cc = Command::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile); assert(cc.Succeeded()); IncreaseBuildingCount(t, type); @@ -2337,7 +2337,7 @@ static inline bool CanBuildHouseHere(TileIndex tile, bool noslope) if (IsBridgeAbove(tile)) return false; /* can we clear the land? */ - return Command::Do(DC_AUTO | DC_NO_WATER, tile, 0, 0, {}).Succeeded(); + return Command::Do(DC_AUTO | DC_NO_WATER, tile).Succeeded(); } @@ -2955,7 +2955,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id) /* Non-oil rig stations are always a problem. */ if (!(st->facilities & FACIL_AIRPORT) || st->airport.type != AT_OILRIG) return CMD_ERROR; /* We can only automatically delete oil rigs *if* there's no vehicle on them. */ - CommandCost ret = Command::Do(flags, st->airport.tile, 0, 0, {}); + CommandCost ret = Command::Do(flags, st->airport.tile); if (ret.Failed()) return ret; } } @@ -2971,7 +2971,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id) * tile was already deleted earlier in the loop. */ for (TileIndex current_tile = 0; current_tile < MapSize(); ++current_tile) { if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) { - CommandCost ret = Command::Do(flags, current_tile, 0, 0, {}); + CommandCost ret = Command::Do(flags, current_tile); if (ret.Failed()) return ret; } } @@ -3014,7 +3014,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id) break; } if (try_clear) { - CommandCost ret = Command::Do(flags, current_tile, 0, 0, {}); + CommandCost ret = Command::Do(flags, current_tile); if (ret.Failed()) return ret; } } @@ -3090,7 +3090,7 @@ static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags) static bool TryClearTile(TileIndex tile) { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); - CommandCost r = Command::Do(DC_NONE, tile, 0, 0, {}); + CommandCost r = Command::Do(DC_NONE, tile); cur_company.Restore(); return r.Succeeded(); } @@ -3162,7 +3162,7 @@ static CommandCost TownActionBuildStatue(Town *t, DoCommandFlag flags) if (flags & DC_EXEC) { Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); - Command::Do(DC_EXEC, statue_data.best_position, 0, 0, {}); + Command::Do(DC_EXEC, statue_data.best_position); cur_company.Restore(); BuildObject(OBJECT_STATUE, statue_data.best_position, _current_company, t); SetBit(t->statues, _current_company); // Once found and built, "inform" the Town. @@ -3767,7 +3767,7 @@ static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, int z } } - return Command::Do(flags, tile, 0, 0, {}); + return Command::Do(flags, tile); } /** Tile callback functions for a town */ diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index 79eaa04215..123255dd47 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -462,7 +462,7 @@ CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 switch (GetRawClearGround(current_tile)) { case CLEAR_FIELDS: case CLEAR_ROCKS: { - CommandCost ret = Command::Do(flags, current_tile, 0, 0, {}); + CommandCost ret = Command::Do(flags, current_tile); if (ret.Failed()) return ret; cost.AddCost(ret); break; @@ -883,7 +883,7 @@ void InitializeTrees() static CommandCost TerraformTile_Trees(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { - return Command::Do(flags, tile, 0, 0, {}); + return Command::Do(flags, tile); } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 14ff79854d..4b95e2de0f 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -412,7 +412,7 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex ti bool allow_on_slopes = (_settings_game.construction.build_on_slopes && transport_type != TRANSPORT_WATER); /* Try and clear the start landscape */ - CommandCost ret = Command::Do(flags, tile_start, 0, 0, {}); + CommandCost ret = Command::Do(flags, tile_start); if (ret.Failed()) return ret; cost = ret; @@ -420,7 +420,7 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex ti cost.AddCost(terraform_cost_north); /* Try and clear the end landscape */ - ret = Command::Do(flags, tile_end, 0, 0, {}); + ret = Command::Do(flags, tile_end); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -492,7 +492,7 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex ti default: not_valid_below:; /* try and clear the middle landscape */ - ret = Command::Do(flags, tile, 0, 0, {}); + ret = Command::Do(flags, tile); if (ret.Failed()) return ret; cost.AddCost(ret); break; @@ -663,7 +663,7 @@ CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportT if (HasTileWaterGround(start_tile)) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER); - CommandCost ret = Command::Do(flags, start_tile, 0, 0, {}); + CommandCost ret = Command::Do(flags, start_tile); if (ret.Failed()) return ret; /* XXX - do NOT change 'ret' in the loop, as it is used as the price @@ -723,7 +723,7 @@ CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportT if (HasTileWaterGround(end_tile)) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER); /* Clear the tile in any case */ - ret = Command::Do(flags, end_tile, 0, 0, {}); + ret = Command::Do(flags, end_tile); if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND); cost.AddCost(ret); @@ -755,7 +755,7 @@ CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportT assert(coa_index < UINT_MAX); // more than 2**32 cleared areas would be a bug in itself coa = nullptr; - ret = Command::Do(flags, end_tile, end_tileh & start_tileh, 0, {}); + ret = Command::Do(flags, end_tile, end_tileh & start_tileh, false); _cleared_object_areas[(uint)coa_index].first_tile = old_first_tile; if (ret.Failed()) return_cmd_error(STR_ERROR_UNABLE_TO_EXCAVATE_LAND); cost.AddCost(ret); @@ -1837,7 +1837,7 @@ static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner if (tt == TRANSPORT_RAIL) { /* Since all of our vehicles have been removed, it is safe to remove the rail * bridge / tunnel. */ - [[maybe_unused]] CommandCost ret = Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); + [[maybe_unused]] CommandCost ret = Command::Do(DC_EXEC | DC_BANKRUPT, tile); assert(ret.Succeeded()); } else { /* In any other case, we can safely reassign the ownership to OWNER_NONE. */ @@ -2028,7 +2028,7 @@ static CommandCost TerraformTile_TunnelBridge(TileIndex tile, DoCommandFlag flag if (res.Succeeded() && (z_old == z_new) && (tileh_old == tileh_new)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } - return Command::Do(flags, tile, 0, 0, {}); + return Command::Do(flags, tile); } extern const TileTypeProcs _tile_type_tunnelbridge_procs = { diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index ee911312ef..c02a1e9b4f 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -121,13 +121,13 @@ CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis) CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_DEPOT_SHIP]); bool add_cost = !IsWaterTile(tile); - CommandCost ret = Command::Do(flags | DC_AUTO, tile, 0, 0, {}); + CommandCost ret = Command::Do(flags | DC_AUTO, tile); if (ret.Failed()) return ret; if (add_cost) { cost.AddCost(ret); } add_cost = !IsWaterTile(tile2); - ret = Command::Do(flags | DC_AUTO, tile2, 0, 0, {}); + ret = Command::Do(flags | DC_AUTO, tile2); if (ret.Failed()) return ret; if (add_cost) { cost.AddCost(ret); @@ -305,13 +305,13 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag /* middle tile */ WaterClass wc_middle = HasTileWaterGround(tile) ? GetWaterClass(tile) : WATER_CLASS_CANAL; - ret = Command::Do(flags, tile, 0, 0, {}); + ret = Command::Do(flags, tile); if (ret.Failed()) return ret; cost.AddCost(ret); /* lower tile */ if (!IsWaterTile(tile - delta)) { - ret = Command::Do(flags, tile - delta, 0, 0, {}); + ret = Command::Do(flags, tile - delta); if (ret.Failed()) return ret; cost.AddCost(ret); cost.AddCost(_price[PR_BUILD_CANAL]); @@ -323,7 +323,7 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag /* upper tile */ if (!IsWaterTile(tile + delta)) { - ret = Command::Do(flags, tile + delta, 0, 0, {}); + ret = Command::Do(flags, tile + delta); if (ret.Failed()) return ret; cost.AddCost(ret); cost.AddCost(_price[PR_BUILD_CANAL]); @@ -473,7 +473,7 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_t /* Outside the editor, prevent building canals over your own or OWNER_NONE owned canals */ if (water && IsCanal(current_tile) && _game_mode != GM_EDITOR && (IsTileOwner(current_tile, _current_company) || IsTileOwner(current_tile, OWNER_NONE))) continue; - ret = Command::Do(flags, current_tile, 0, 0, {}); + ret = Command::Do(flags, current_tile); if (ret.Failed()) return ret; if (!water) cost.AddCost(ret); @@ -1128,7 +1128,7 @@ void DoFloodTile(TileIndex target) FALLTHROUGH; case MP_CLEAR: - if (Command::Do(DC_EXEC, target, 0, 0, {}).Succeeded()) { + if (Command::Do(DC_EXEC, target).Succeeded()) { MakeShore(target); MarkTileDirtyByTile(target); flooded = true; @@ -1143,7 +1143,7 @@ void DoFloodTile(TileIndex target) FloodVehicles(target); /* flood flat tile */ - if (Command::Do(DC_EXEC, target, 0, 0, {}).Succeeded()) { + if (Command::Do(DC_EXEC, target).Succeeded()) { MakeSea(target); MarkTileDirtyByTile(target); flooded = true; @@ -1195,7 +1195,7 @@ static void DoDryUp(TileIndex tile) case MP_WATER: assert(IsCoast(tile)); - if (Command::Do(DC_EXEC, tile, 0, 0, {}).Succeeded()) { + if (Command::Do(DC_EXEC, tile).Succeeded()) { MakeClear(tile, CLEAR_GRASS, 3); MarkTileDirtyByTile(tile); } @@ -1354,7 +1354,7 @@ static void ChangeTileOwner_Water(TileIndex tile, Owner old_owner, Owner new_own } /* Remove depot */ - if (IsShipDepot(tile)) Command::Do(DC_EXEC | DC_BANKRUPT, tile, 0, 0, {}); + if (IsShipDepot(tile)) Command::Do(DC_EXEC | DC_BANKRUPT, tile); /* Set owner of canals and locks ... and also canal under dock there was before. * Check if the new owner after removing depot isn't OWNER_WATER. */ @@ -1374,7 +1374,7 @@ static CommandCost TerraformTile_Water(TileIndex tile, DoCommandFlag flags, int /* Canals can't be terraformed */ if (IsWaterTile(tile) && IsCanal(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST); - return Command::Do(DC_EXEC, tile, 0, 0, {}); + return Command::Do(DC_EXEC, tile); } diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 85c52c98fa..56095a0796 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -302,7 +302,7 @@ CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile) CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_WAYPOINT_BUOY]); if (!IsWaterTile(tile)) { - CommandCost ret = Command::Do(flags | DC_AUTO, tile, 0, 0, {}); + CommandCost ret = Command::Do(flags | DC_AUTO, tile); if (ret.Failed()) return ret; cost.AddCost(ret); } From 58cff7b081ce9ea4b5314cf8324ca60607389d15 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 21 Nov 2021 23:03:44 +0100 Subject: [PATCH 32/60] Codechange: Un-bitstuff the remaining on-map commands. --- src/company_gui.cpp | 2 +- src/industry_cmd.cpp | 48 ++++++++++---------------- src/industry_cmd.h | 9 +++-- src/industry_gui.cpp | 9 +++-- src/object_cmd.cpp | 11 +++--- src/object_cmd.h | 3 +- src/object_gui.cpp | 2 +- src/script/api/script_company.cpp | 2 +- src/script/api/script_industry.cpp | 8 ++--- src/script/api/script_industrytype.cpp | 4 +-- src/script/api/script_objecttype.cpp | 2 +- src/script/api/script_sign.cpp | 6 ++-- src/script/api/script_tile.cpp | 4 +-- src/script/api/script_viewport.cpp | 6 ++-- src/signs_cmd.cpp | 16 ++++----- src/signs_cmd.h | 5 +-- src/signs_gui.cpp | 2 +- src/terraform_gui.cpp | 2 +- src/tree_cmd.cpp | 12 +++---- src/tree_cmd.h | 2 +- src/tree_gui.cpp | 4 +-- src/viewport.cpp | 12 +++---- src/viewport_cmd.h | 3 +- src/viewport_type.h | 2 +- 24 files changed, 80 insertions(+), 96 deletions(-) diff --git a/src/company_gui.cpp b/src/company_gui.cpp index cefab6d127..7e65b43ac2 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -2618,7 +2618,7 @@ struct CompanyWindow : Window void OnPlaceObject(Point pt, TileIndex tile) override { - if (Command::Post(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS, tile, OBJECT_HQ, 0, {}) && !_shift_pressed) { + if (Command::Post(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS, tile, OBJECT_HQ, 0) && !_shift_pressed) { ResetObjectToPlace(); this->RaiseButtons(); } diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 2c45a84729..ef5f24315a 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1977,17 +1977,14 @@ static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, Do * Build/Fund an industry * @param flags of operations to conduct * @param tile tile where industry is built - * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 7) - industry type see build_industry.h and see industry.h - * - p1 = (bit 8 - 15) - first layout to try - * - p1 = (bit 16 ) - 0 = prospect, 1 = fund (only valid if current company is DEITY) - * @param p2 seed to use for desyncfree randomisations - * @param text unused + * @param it industry type see build_industry.h and see industry.h + * @param first_layout first layout to try + * @param fund false = prospect, true = fund (only valid if current company is DEITY) + * @param seed seed to use for desyncfree randomisations * @return the cost of this operation or an error */ -CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType it, uint32 first_layout, bool fund, uint32 seed) { - IndustryType it = GB(p1, 0, 8); if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR; const IndustrySpec *indspec = GetIndustrySpec(it); @@ -2006,12 +2003,12 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, uint32 p1, uin } Randomizer randomizer; - randomizer.SetSeed(p2); - uint16 random_initial_bits = GB(p2, 0, 16); + randomizer.SetSeed(seed); + uint16 random_initial_bits = GB(seed, 0, 16); uint32 random_var8f = randomizer.Next(); size_t num_layouts = indspec->layouts.size(); CommandCost ret = CommandCost(STR_ERROR_SITE_UNSUITABLE); - const bool deity_prospect = _current_company == OWNER_DEITY && !HasBit(p1, 16); + const bool deity_prospect = _current_company == OWNER_DEITY && !fund; Industry *ind = nullptr; if (deity_prospect || (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry())) { @@ -2041,7 +2038,7 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, uint32 p1, uin cur_company.Restore(); } } else { - size_t layout = GB(p1, 8, 8); + size_t layout = first_layout; if (layout >= num_layouts) return CMD_ERROR; /* Check subsequently each layout, starting with the given layout in p1 */ @@ -2065,40 +2062,31 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, uint32 p1, uin /** * Change industry properties * @param flags Type of operation. - * @param tile Unused. - * @param p1 IndustryID - * @param p2 various bitstuffed elements - * - p2 = (bit 0 - 7) - IndustryAction to perform - * - p2 = (bit 8 - 15) - IndustryControlFlags - * (only used with set control flags) - * - p2 = (bit 16 - 23) - CompanyID to set or INVALID_OWNER (available to everyone) or - * OWNER_NONE (neutral stations only) or OWNER_DEITY (no one) - * (only used with set exclusive supplier / consumer) + * @param ind_id IndustryID + * @param action IndustryAction to perform + * @param ctlflags IndustryControlFlags (only used with set control flags) + * @param company_id CompanyID to set or INVALID_OWNER (available to everyone) or + * OWNER_NONE (neutral stations only) or OWNER_DEITY (no one) + * (only used with set exclusive supplier / consumer) * @param text - Additional industry text (only used with set text action) * @return Empty cost or an error. */ -CommandCost CmdIndustryCtrl(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdIndustryCtrl(DoCommandFlag flags, IndustryID ind_id, IndustryAction action, IndustryControlFlags ctlflags, Owner company_id, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - Industry *ind = Industry::GetIfValid(p1); + Industry *ind = Industry::GetIfValid(ind_id); if (ind == nullptr) return CMD_ERROR; - auto action = static_cast(GB(p2, 0, 8)); - switch (action) { case IndustryAction::SetControlFlags: { - IndustryControlFlags ctlflags = (IndustryControlFlags)GB(p2, 8, 8) & INDCTL_MASK; - - if (flags & DC_EXEC) ind->ctlflags = ctlflags; + if (flags & DC_EXEC) ind->ctlflags = ctlflags & INDCTL_MASK; break; } case IndustryAction::SetExclusiveSupplier: case IndustryAction::SetExclusiveConsumer: { - Owner company_id = (Owner)GB(p2, 16, 8); - if (company_id != OWNER_NONE && company_id != INVALID_OWNER && company_id != OWNER_DEITY && !Company::IsValidID(company_id)) return CMD_ERROR; diff --git a/src/industry_cmd.h b/src/industry_cmd.h index 150b59da9b..b4d965f649 100644 --- a/src/industry_cmd.h +++ b/src/industry_cmd.h @@ -11,9 +11,14 @@ #define INDUSTRY_CMD_H #include "command_type.h" +#include "company_type.h" +#include "industry_type.h" -CommandProc CmdBuildIndustry; -CommandProc CmdIndustryCtrl; +enum class IndustryAction : byte; +enum IndustryControlFlags : byte; + +CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType it, uint32 first_layout, bool fund, uint32 seed); +CommandCost CmdIndustryCtrl(DoCommandFlag flags, IndustryID ind_id, IndustryAction action, IndustryControlFlags ctlflags, Owner company_id, const std::string &text); DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_INDUSTRY_CTRL, CmdIndustryCtrl, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index b66d4f8bfc..8bd4dc5741 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -228,8 +228,7 @@ void CcBuildIndustry(Commands cmd, const CommandCost &result, TileIndex tile, co { if (result.Succeeded()) return; - auto [tile_, p1, p2, text] = EndianBufferReader::ToValue::Args>(data); - uint8 indtype = GB(p1, 0, 8); + auto [tile_, indtype, first_layout, fund, seed] = EndianBufferReader::ToValue::Args>(data); if (indtype < NUM_INDUSTRYTYPES) { const IndustrySpec *indsp = GetIndustrySpec(indtype); if (indsp->enabled) { @@ -679,7 +678,7 @@ public: case WID_DPI_FUND_WIDGET: { if (this->selected_type != INVALID_INDUSTRYTYPE) { if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && GetIndustrySpec(this->selected_type)->IsRawIndustry()) { - Command::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, 0, this->selected_type, InteractiveRandom(), {}); + Command::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, 0, this->selected_type, 0, false, InteractiveRandom()); this->HandleButtonClick(WID_DPI_FUND_WIDGET); } else { HandlePlacePushButton(this, WID_DPI_FUND_WIDGET, SPR_CURSOR_INDUSTRY, HT_RECT); @@ -716,13 +715,13 @@ public: Backup old_generating_world(_generating_world, true, FILE_LINE); _ignore_restrictions = true; - Command::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, &CcBuildIndustry, tile, (layout_index << 8) | this->selected_type, seed, {}); + Command::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, &CcBuildIndustry, tile, this->selected_type, layout_index, false, seed); cur_company.Restore(); old_generating_world.Restore(); _ignore_restrictions = false; } else { - success = Command::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, (layout_index << 8) | this->selected_type, seed, {}); + success = Command::Post(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY, tile, this->selected_type, layout_index, false, seed); } /* If an industry has been built, just reset the cursor and the system */ diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 9968424e0a..b6ea0b4084 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -199,18 +199,15 @@ static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags); * Build an object object * @param flags type of operation * @param tile tile where the object will be located - * @param p1 the object type to build - * @param p2 the view for the object - * @param text unused + * @param type the object type to build + * @param view the view for the object * @return the cost of this operation or an error */ -CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type, uint8 view) { CommandCost cost(EXPENSES_CONSTRUCTION); - ObjectType type = (ObjectType)GB(p1, 0, 16); if (type >= NUM_OBJECTS) return CMD_ERROR; - uint8 view = GB(p2, 0, 2); const ObjectSpec *spec = ObjectSpec::Get(type); if (_game_mode == GM_NORMAL && !spec->IsAvailable() && !_generating_world) return CMD_ERROR; if ((_game_mode == GM_EDITOR || _generating_world) && !spec->WasEverAvailable()) return CMD_ERROR; @@ -777,7 +774,7 @@ void GenerateObjects() default: uint8 view = RandomRange(spec->views); - if (CmdBuildObject(DC_EXEC | DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, RandomTile(), i, view, {}).Succeeded()) amount--; + if (CmdBuildObject(DC_EXEC | DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, RandomTile(), i, view).Succeeded()) amount--; break; } } diff --git a/src/object_cmd.h b/src/object_cmd.h index b7119afc38..ea7412544c 100644 --- a/src/object_cmd.h +++ b/src/object_cmd.h @@ -11,8 +11,9 @@ #define OBJECT_CMD_H #include "command_type.h" +#include "object_type.h" -CommandProc CmdBuildObject; +CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type, uint8 view); DEF_CMD_TRAIT(CMD_BUILD_OBJECT, CmdBuildObject, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 562af15ae8..fa90eb43b6 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -544,7 +544,7 @@ public: { ObjectClass *objclass = ObjectClass::Get(_selected_object_class); Command::Post(STR_ERROR_CAN_T_BUILD_OBJECT, CcTerraform, - tile, objclass->GetSpec(_selected_object_index)->Index(), _selected_object_view, {}); + tile, objclass->GetSpec(_selected_object_index)->Index(), _selected_object_view); } void OnPlaceObjectAbort() override diff --git a/src/script/api/script_company.cpp b/src/script/api/script_company.cpp index c8f8a616fb..1cc69bc93f 100644 --- a/src/script/api/script_company.cpp +++ b/src/script/api/script_company.cpp @@ -252,7 +252,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, OBJECT_HQ, 0, {}); + return ScriptObject::Command::Do(tile, OBJECT_HQ, 0); } /* static */ TileIndex ScriptCompany::GetCompanyHQ(CompanyID company) diff --git a/src/script/api/script_industry.cpp b/src/script/api/script_industry.cpp index afcaee5547..ca0eaafc43 100644 --- a/src/script/api/script_industry.cpp +++ b/src/script/api/script_industry.cpp @@ -60,7 +60,7 @@ } EnforcePrecondition(false, IsValidIndustry(industry_id)); - return ScriptObject::Command::Do(0, industry_id, static_cast(IndustryAction::SetText), std::string{ encoded_text ? encoded_text : "" }); + return ScriptObject::Command::Do(industry_id, IndustryAction::SetText, INDCTL_NONE, INVALID_OWNER, std::string{ encoded_text ? encoded_text : "" }); } /* static */ ScriptIndustry::CargoAcceptState ScriptIndustry::IsCargoAccepted(IndustryID industry_id, CargoID cargo_id) @@ -258,7 +258,7 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag if (ScriptObject::GetCompany() != OWNER_DEITY) return false; if (!IsValidIndustry(industry_id)) return false; - return ScriptObject::Command::Do(0, industry_id, 0 | ((control_flags & ::INDCTL_MASK) << 8), {}); + return ScriptObject::Command::Do(industry_id, IndustryAction::SetControlFlags, (::IndustryControlFlags)control_flags & ::INDCTL_MASK, INVALID_OWNER, {}); } /* static */ ScriptCompany::CompanyID ScriptIndustry::GetExclusiveSupplier(IndustryID industry_id) @@ -277,7 +277,7 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag auto company = ScriptCompany::ResolveCompanyID(company_id); ::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company); - return ScriptObject::Command::Do(0, industry_id, 1 | (((uint8)owner) << 16), {}); + return ScriptObject::Command::Do(industry_id, IndustryAction::SetExclusiveSupplier, INDCTL_NONE, owner, {}); } /* static */ ScriptCompany::CompanyID ScriptIndustry::GetExclusiveConsumer(IndustryID industry_id) @@ -296,5 +296,5 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag auto company = ScriptCompany::ResolveCompanyID(company_id); ::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company); - return ScriptObject::Command::Do(0, industry_id, 2 | (((uint8)owner) << 16), {}); + return ScriptObject::Command::Do(industry_id, IndustryAction::SetExclusiveConsumer, INDCTL_NONE, owner, {}); } diff --git a/src/script/api/script_industrytype.cpp b/src/script/api/script_industrytype.cpp index ebe28c4067..ce8d63e512 100644 --- a/src/script/api/script_industrytype.cpp +++ b/src/script/api/script_industrytype.cpp @@ -123,7 +123,7 @@ uint32 seed = ::InteractiveRandom(); uint32 layout_index = ::InteractiveRandomRange((uint32)::GetIndustrySpec(industry_type)->layouts.size()); - return ScriptObject::Command::Do(tile, (1 << 16) | (layout_index << 8) | industry_type, seed, {}); + return ScriptObject::Command::Do(tile, industry_type, layout_index, true, seed); } /* static */ bool ScriptIndustryType::ProspectIndustry(IndustryType industry_type) @@ -131,7 +131,7 @@ EnforcePrecondition(false, CanProspectIndustry(industry_type)); uint32 seed = ::InteractiveRandom(); - return ScriptObject::Command::Do(0, industry_type, seed, {}); + return ScriptObject::Command::Do(0, industry_type, 0, false, seed); } /* static */ bool ScriptIndustryType::IsBuiltOnWater(IndustryType industry_type) diff --git a/src/script/api/script_objecttype.cpp b/src/script/api/script_objecttype.cpp index a4a8ef9843..cd97761de2 100644 --- a/src/script/api/script_objecttype.cpp +++ b/src/script/api/script_objecttype.cpp @@ -42,5 +42,5 @@ EnforcePrecondition(false, IsValidObjectType(object_type)); EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, object_type, view, {}); + return ScriptObject::Command::Do(tile, object_type, view); } diff --git a/src/script/api/script_sign.cpp b/src/script/api/script_sign.cpp index 6062497f0c..c95093a791 100644 --- a/src/script/api/script_sign.cpp +++ b/src/script/api/script_sign.cpp @@ -42,7 +42,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::Command::Do(0, sign_id, 0, text); + return ScriptObject::Command::Do(sign_id, text); } /* static */ char *ScriptSign::GetName(SignID sign_id) @@ -64,7 +64,7 @@ /* static */ bool ScriptSign::RemoveSign(SignID sign_id) { EnforcePrecondition(false, IsValidSign(sign_id)); - return ScriptObject::Command::Do(0, sign_id, 0, ""); + return ScriptObject::Command::Do(sign_id, ""); } /* static */ SignID ScriptSign::BuildSign(TileIndex location, Text *name) @@ -77,7 +77,7 @@ EnforcePreconditionEncodedText(INVALID_SIGN, text); EnforcePreconditionCustomError(INVALID_SIGN, ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnSignID, location, 0, 0, text)) return INVALID_SIGN; + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnSignID, location, text)) return INVALID_SIGN; /* In case of test-mode, we return SignID 0 */ return 0; diff --git a/src/script/api/script_tile.cpp b/src/script/api/script_tile.cpp index 8be74c0304..d8bcc399fa 100644 --- a/src/script/api/script_tile.cpp +++ b/src/script/api/script_tile.cpp @@ -287,7 +287,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, TREE_INVALID, tile, {}); + return ScriptObject::Command::Do(tile, tile, TREE_INVALID); } /* static */ bool ScriptTile::PlantTreeRectangle(TileIndex tile, uint width, uint height) @@ -298,7 +298,7 @@ EnforcePrecondition(false, height >= 1 && height <= 20); TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1); - return ScriptObject::Command::Do(tile, TREE_INVALID, end_tile, {}); + return ScriptObject::Command::Do(tile, end_tile, TREE_INVALID); } /* static */ bool ScriptTile::IsWithinTownInfluence(TileIndex tile, TownID town_id) diff --git a/src/script/api/script_viewport.cpp b/src/script/api/script_viewport.cpp index 7d57bffb37..86a4c12dbd 100644 --- a/src/script/api/script_viewport.cpp +++ b/src/script/api/script_viewport.cpp @@ -31,7 +31,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, VST_EVERYONE, 0, {}); + return ScriptObject::Command::Do(tile, VST_EVERYONE, 0); } /* static */ bool ScriptViewport::ScrollCompanyClientsTo(ScriptCompany::CompanyID company, TileIndex tile) @@ -42,7 +42,7 @@ company = ScriptCompany::ResolveCompanyID(company); EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); - return ScriptObject::Command::Do(tile, VST_COMPANY, company, {}); + return ScriptObject::Command::Do(tile, VST_COMPANY, company); } /* static */ bool ScriptViewport::ScrollClientTo(ScriptClient::ClientID client, TileIndex tile) @@ -54,5 +54,5 @@ client = ScriptClient::ResolveClientID(client); EnforcePrecondition(false, client != ScriptClient::CLIENT_INVALID); - return ScriptObject::Command::Do(tile, VST_CLIENT, client, {}); + return ScriptObject::Command::Do(tile, VST_CLIENT, client); } diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index 00baf45a88..8d20137b4a 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -32,12 +32,10 @@ SignID _new_sign_id; * but everybody is able to rename/remove it. * @param tile tile to place sign at * @param flags type of operation - * @param p1 unused - * @param p2 unused - * @param text unused + * @param text contents of the sign * @return the cost of this operation or an error */ -CommandCost CmdPlaceSign(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdPlaceSign(DoCommandFlag flags, TileIndex tile, const std::string &text) { /* Try to locate a new sign */ if (!Sign::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_SIGNS); @@ -69,16 +67,14 @@ CommandCost CmdPlaceSign(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 * Rename a sign. If the new name of the sign is empty, we assume * the user wanted to delete it. So delete it. Ownership of signs * has no meaning/effect whatsoever except for eyecandy - * @param tile unused * @param flags type of operation - * @param p1 index of the sign to be renamed/removed - * @param p2 unused + * @param sign_id index of the sign to be renamed/removed * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameSign(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameSign(DoCommandFlag flags, SignID sign_id, const std::string &text) { - Sign *si = Sign::GetIfValid(p1); + Sign *si = Sign::GetIfValid(sign_id); if (si == nullptr) return CMD_ERROR; if (!CompanyCanRenameSign(si)) return CMD_ERROR; @@ -132,5 +128,5 @@ void CcPlaceSign(Commands cmd, const CommandCost &result, TileIndex tile, const */ void PlaceProc_Sign(TileIndex tile) { - Command::Post(STR_ERROR_CAN_T_PLACE_SIGN_HERE, CcPlaceSign, tile, 0, 0, {}); + Command::Post(STR_ERROR_CAN_T_PLACE_SIGN_HERE, CcPlaceSign, tile, {}); } diff --git a/src/signs_cmd.h b/src/signs_cmd.h index 85f0ffbdf5..1c4e1b4657 100644 --- a/src/signs_cmd.h +++ b/src/signs_cmd.h @@ -11,9 +11,10 @@ #define SIGNS_CMD_H #include "command_type.h" +#include "signs_type.h" -CommandProc CmdPlaceSign; -CommandProc CmdRenameSign; +CommandCost CmdPlaceSign(DoCommandFlag flags, TileIndex tile, const std::string &text); +CommandCost CmdRenameSign(DoCommandFlag flags, SignID sign_id, const std::string &text); DEF_CMD_TRAIT(CMD_PLACE_SIGN, CmdPlaceSign, CMD_DEITY, CMDT_OTHER_MANAGEMENT) DEF_CMD_TRAIT(CMD_RENAME_SIGN, CmdRenameSign, CMD_DEITY, CMDT_OTHER_MANAGEMENT) diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index b10e6d38c5..a3685c5c50 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -414,7 +414,7 @@ Window *ShowSignList() static bool RenameSign(SignID index, const char *text) { bool remove = StrEmpty(text); - Command::Post(StrEmpty(text) ? STR_ERROR_CAN_T_DELETE_SIGN : STR_ERROR_CAN_T_CHANGE_SIGN_NAME, 0, index, 0, text); + Command::Post(StrEmpty(text) ? STR_ERROR_CAN_T_DELETE_SIGN : STR_ERROR_CAN_T_CHANGE_SIGN_NAME, index, text); return remove; } diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index c12f10dedc..2e3fec0956 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -243,7 +243,7 @@ struct TerraformToolbarWindow : Window { break; case WID_TT_BUY_LAND: // Buy land button - Command::Post(STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0, {}); + Command::Post(STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0); break; case WID_TT_PLACE_SIGN: // Place sign button diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index 123255dd47..c98758062f 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -382,25 +382,23 @@ void GenerateTrees() * Plant a tree. * @param flags type of operation * @param tile end tile of area-drag - * @param p1 tree type, TREE_INVALID means random. - * @param p2 start tile of area-drag of tree plantation - * @param text unused + * @param start_tile start tile of area-drag of tree plantation + * @param tree_to_plant tree type, TREE_INVALID means random. * @return the cost of this operation or an error */ -CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant) { StringID msg = INVALID_STRING_ID; CommandCost cost(EXPENSES_OTHER); - const byte tree_to_plant = GB(p1, 0, 8); // We cannot use Extract as min and max are climate specific. - if (p2 >= MapSize()) return CMD_ERROR; + if (start_tile >= MapSize()) return CMD_ERROR; /* Check the tree type within the current climate */ if (tree_to_plant != TREE_INVALID && !IsInsideBS(tree_to_plant, _tree_base_by_landscape[_settings_game.game_creation.landscape], _tree_count_by_landscape[_settings_game.game_creation.landscape])) return CMD_ERROR; Company *c = (_game_mode != GM_EDITOR) ? Company::GetIfValid(_current_company) : nullptr; int limit = (c == nullptr ? INT32_MAX : GB(c->tree_limit, 16, 16)); - TileArea ta(tile, (TileIndex)p2); + TileArea ta(tile, start_tile); for (TileIndex current_tile : ta) { switch (GetTileType(current_tile)) { case MP_TREES: diff --git a/src/tree_cmd.h b/src/tree_cmd.h index de8d00179b..8f2199e3e8 100644 --- a/src/tree_cmd.h +++ b/src/tree_cmd.h @@ -12,7 +12,7 @@ #include "command_type.h" -CommandProc CmdPlantTree; +CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant); DEF_CMD_TRAIT(CMD_PLANT_TREE, CmdPlantTree, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index 794135716b..0b0eeda22b 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -231,7 +231,7 @@ public: TileIndex tile = TileVirtXY(pt.x, pt.y); if (this->mode == PM_NORMAL) { - Command::Post(tile, this->tree_to_plant, tile, {}); + Command::Post(tile, tile, this->tree_to_plant); } else { this->DoPlantForest(tile); } @@ -241,7 +241,7 @@ public: void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL && pt.x != -1 && select_proc == DDSP_PLANT_TREES) { - Command::Post(STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, this->tree_to_plant, start_tile, {}); + Command::Post(STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, start_tile, this->tree_to_plant); } } diff --git a/src/viewport.cpp b/src/viewport.cpp index 1509b028c6..69db0aeab5 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -3468,23 +3468,21 @@ void InitializeSpriteSorter() * Scroll players main viewport. * @param flags type of operation * @param tile tile to center viewport on - * @param p1 ViewportScrollTarget of scroll target - * @param p2 company or client id depending on the target - * @param text unused + * @param target ViewportScrollTarget of scroll target + * @param ref company or client id depending on the target * @return the cost of this operation or an error */ -CommandCost CmdScrollViewport(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdScrollViewport(DoCommandFlag flags, TileIndex tile, ViewportScrollTarget target, uint32 ref) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - ViewportScrollTarget target = (ViewportScrollTarget)p1; switch (target) { case VST_EVERYONE: break; case VST_COMPANY: - if (_local_company != (CompanyID)p2) return CommandCost(); + if (_local_company != (CompanyID)ref) return CommandCost(); break; case VST_CLIENT: - if (_network_own_client_id != (ClientID)p2) return CommandCost(); + if (_network_own_client_id != (ClientID)ref) return CommandCost(); break; default: return CMD_ERROR; diff --git a/src/viewport_cmd.h b/src/viewport_cmd.h index f549d755e3..0cae1d9317 100644 --- a/src/viewport_cmd.h +++ b/src/viewport_cmd.h @@ -11,8 +11,9 @@ #define VIEWPORT_CMD_H #include "command_type.h" +#include "viewport_type.h" -CommandProc CmdScrollViewport; +CommandCost CmdScrollViewport(DoCommandFlag flags, TileIndex tile, ViewportScrollTarget target, uint32 ref); DEF_CMD_TRAIT(CMD_SCROLL_VIEWPORT, CmdScrollViewport, CMD_DEITY, CMDT_OTHER_MANAGEMENT) diff --git a/src/viewport_type.h b/src/viewport_type.h index 6665af19e7..a317734b61 100644 --- a/src/viewport_type.h +++ b/src/viewport_type.h @@ -146,7 +146,7 @@ enum ViewportDragDropSelectionProcess { /** * Target of the viewport scrolling GS method */ -enum ViewportScrollTarget { +enum ViewportScrollTarget : byte { VST_EVERYONE, ///< All players VST_COMPANY, ///< All players in specific company VST_CLIENT, ///< Single player From 13528bfcd0f11d738ec23409e26052e70dd233f6 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Tue, 23 Nov 2021 01:05:58 +0100 Subject: [PATCH 33/60] Codechange: Un-bitstuff all remaining commands. --- src/ai/ai_gui.cpp | 4 +- src/autoreplace_gui.cpp | 2 +- src/cheat_gui.cpp | 2 +- src/command_type.h | 20 ------ src/company_cmd.cpp | 51 +++++--------- src/company_cmd.h | 13 ++-- src/company_gui.cpp | 20 +++--- src/console_cmds.cpp | 4 +- src/core/overflowsafe_type.hpp | 5 +- src/economy.cpp | 26 ++----- src/economy_cmd.h | 7 +- src/fios_gui.cpp | 4 +- src/highscore_gui.cpp | 8 +-- src/linkgraph/linkgraphschedule.cpp | 4 +- src/livery.h | 2 +- src/main_gui.cpp | 2 +- src/misc/endian_buffer.hpp | 7 ++ src/misc_cmd.cpp | 93 ++++++++++---------------- src/misc_cmd.h | 19 ++++-- src/network/network.cpp | 4 +- src/network/network_server.cpp | 2 +- src/news_cmd.h | 4 +- src/news_gui.cpp | 30 ++++----- src/news_type.h | 4 +- src/openttd.cpp | 8 +-- src/script/api/script_company.cpp | 22 +++--- src/script/api/script_controller.cpp | 2 +- src/script/api/script_event_types.cpp | 2 +- src/script/api/script_game.cpp | 4 +- src/script/api/script_gamesettings.cpp | 2 +- src/script/api/script_group.cpp | 2 +- src/script/api/script_news.cpp | 2 +- src/script/api/script_subsidy.cpp | 2 +- src/settings.cpp | 34 +++++----- src/settings_cmd.h | 4 +- src/subsidy.cpp | 22 ++---- src/subsidy_cmd.h | 3 +- src/toolbar_gui.cpp | 2 +- src/train_cmd.cpp | 2 +- src/vehicle.cpp | 2 +- 40 files changed, 192 insertions(+), 260 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 5e0c720f00..c4a8667620 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -1332,7 +1332,7 @@ struct AIDebugWindow : public Window { } if (all_unpaused) { /* All scripts have been unpaused => unpause the game. */ - Command::Post(0, PM_PAUSED_NORMAL, 0, {}); + Command::Post(PM_PAUSED_NORMAL, false); } } } @@ -1381,7 +1381,7 @@ struct AIDebugWindow : public Window { /* Pause the game. */ if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - Command::Post(0, PM_PAUSED_NORMAL, 1, {}); + Command::Post(PM_PAUSED_NORMAL, true); } /* Highlight row that matched */ diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 00eba4044b..4dae0eedc7 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -547,7 +547,7 @@ public: Command::Post(this->sel_group, GroupFlags::GF_REPLACE_WAGON_REMOVAL, !HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL), _ctrl_pressed); } else { // toggle renew_keep_length - Command::Post(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, "company.renew_keep_length"); + Command::Post("company.renew_keep_length", Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1); } break; } diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index fcc9a3ef07..eb62dc0317 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -55,7 +55,7 @@ static int32 _money_cheat_amount = 10000000; */ static int32 ClickMoneyCheat(int32 p1, int32 p2) { - Command::Post(0, (uint32)(p2 * _money_cheat_amount), 0, {}); + Command::Post(p2 * _money_cheat_amount); return _money_cheat_amount; } diff --git a/src/command_type.h b/src/command_type.h index 59331dc7cc..0424782a23 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -404,26 +404,6 @@ enum CommandPauseLevel { CMDPL_ALL_ACTIONS, ///< All actions may be executed. }; -/** - * Defines the callback type for all command handler functions. - * - * This type defines the function header for all functions which handles a CMD_* command. - * A command handler use the parameters to act according to the meaning of the command. - * The tile parameter defines the tile to perform an action on. - * The flag parameter is filled with flags from the DC_* enumeration. The parameters - * p1 and p2 are filled with parameters for the command like "which road type", "which - * order" or "direction". Each function should mentioned in there doxygen comments - * the usage of these parameters. - * - * @param tile The tile to apply a command on - * @param flags Flags for the command, from the DC_* enumeration - * @param p1 Additional data for the command - * @param p2 Additional data for the command - * @param text Additional text - * @return The CommandCost of the command, which can be succeeded or failed. - */ -typedef CommandCost CommandProc(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text); - template struct CommandFunctionTraitHelper; template diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 87231f3eb6..016a830bf9 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -916,16 +916,11 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID /** * Change the company manager's face. * @param flags operation to perform - * @param tile unused - * @param p1 unused - * @param p2 face bitmasked - * @param text unused + * @param cmf face bitmasked * @return the cost of this operation or an error */ -CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, CompanyManagerFace cmf) { - CompanyManagerFace cmf = (CompanyManagerFace)p2; - if (!IsValidCompanyManagerFace(cmf)) return CMD_ERROR; if (flags & DC_EXEC) { @@ -938,20 +933,13 @@ CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, TileIndex tile, uint32 /** * Change the company's company-colour * @param flags operation to perform - * @param tile unused - * @param p1 bitstuffed: - * p1 bits 0-7 scheme to set - * p1 bit 8 set first/second colour - * @param p2 new colour for vehicles, property, etc. - * @param text unused + * @param scheme scheme to set + * @param primary set first/second colour + * @param colour new colour for vehicles, property, etc. * @return the cost of this operation or an error */ -CommandCost CmdSetCompanyColour(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool primary, Colours colour) { - Colours colour = Extract(p2); - LiveryScheme scheme = Extract(p1); - bool second = HasBit(p1, 8); - if (scheme >= LS_END || (colour >= COLOUR_END && colour != INVALID_COLOUR)) return CMD_ERROR; /* Default scheme can't be reset to invalid. */ @@ -960,14 +948,14 @@ CommandCost CmdSetCompanyColour(DoCommandFlag flags, TileIndex tile, uint32 p1, Company *c = Company::Get(_current_company); /* Ensure no two companies have the same primary colour */ - if (scheme == LS_DEFAULT && !second) { + if (scheme == LS_DEFAULT && primary) { for (const Company *cc : Company::Iterate()) { if (cc != c && cc->colour == colour) return CMD_ERROR; } } if (flags & DC_EXEC) { - if (!second) { + if (primary) { if (scheme != LS_DEFAULT) SB(c->livery[scheme].in_use, 0, 1, colour != INVALID_COLOUR); if (colour == INVALID_COLOUR) colour = (Colours)c->livery[LS_DEFAULT].colour1; c->livery[scheme].colour1 = colour; @@ -1051,13 +1039,10 @@ static bool IsUniqueCompanyName(const std::string &name) /** * Change the name of the company. * @param flags operation to perform - * @param tile unused - * @param p1 unused - * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenameCompany(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenameCompany(DoCommandFlag flags, const std::string &text) { bool reset = text.empty(); @@ -1097,13 +1082,10 @@ static bool IsUniquePresidentName(const std::string &name) /** * Change the name of the president. * @param flags operation to perform - * @param tile unused - * @param p1 unused - * @param p2 unused * @param text the new name or an empty string when resetting to the default * @return the cost of this operation or an error */ -CommandCost CmdRenamePresident(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text) { bool reset = text.empty(); @@ -1121,7 +1103,7 @@ CommandCost CmdRenamePresident(DoCommandFlag flags, TileIndex tile, uint32 p1, u c->president_name = text; if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) { - Command::Do(DC_EXEC, 0, 0, 0, text + " Transport"); + Command::Do(DC_EXEC, text + " Transport"); } } @@ -1182,19 +1164,16 @@ uint32 CompanyInfrastructure::GetTramTotal() const * companies if you have paid off your loan (either explicitly, or implicitly * given the fact that you have more money than loan). * @param flags operation to perform - * @param tile unused - * @param p1 the amount of money to transfer; max 20.000.000 - * @param p2 the company to transfer the money to - * @param text unused + * @param money the amount of money to transfer; max 20.000.000 + * @param dest_company the company to transfer the money to * @return the cost of this operation or an error */ -CommandCost CmdGiveMoney(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdGiveMoney(DoCommandFlag flags, uint32 money, CompanyID dest_company) { if (!_settings_game.economy.give_money) return CMD_ERROR; const Company *c = Company::Get(_current_company); - CommandCost amount(EXPENSES_OTHER, std::min(p1, 20000000LL)); - CompanyID dest_company = (CompanyID)p2; + CommandCost amount(EXPENSES_OTHER, std::min(money, 20000000LL)); /* You can only transfer funds that is in excess of your loan */ if (c->money - c->current_loan < amount.GetCost() || amount.GetCost() < 0) return_cmd_error(STR_ERROR_INSUFFICIENT_FUNDS); diff --git a/src/company_cmd.h b/src/company_cmd.h index 107a77f29c..5ffac5cbde 100644 --- a/src/company_cmd.h +++ b/src/company_cmd.h @@ -11,15 +11,18 @@ #define COMPANY_CMD_H #include "command_type.h" +#include "company_type.h" +#include "livery.h" enum ClientID : uint32; +enum Colours : byte; CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id); -CommandProc CmdGiveMoney; -CommandProc CmdRenameCompany; -CommandProc CmdRenamePresident; -CommandProc CmdSetCompanyManagerFace; -CommandProc CmdSetCompanyColour; +CommandCost CmdGiveMoney(DoCommandFlag flags, uint32 money, CompanyID dest_company); +CommandCost CmdRenameCompany(DoCommandFlag flags, const std::string &text); +CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text); +CommandCost CmdSetCompanyManagerFace(DoCommandFlag flags, CompanyManagerFace cmf); +CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool primary, Colours colour); DEF_CMD_TRAIT(CMD_COMPANY_CTRL, CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID | CMD_NO_EST, CMDT_SERVER_SETTING) DEF_CMD_TRAIT(CMD_GIVE_MONEY, CmdGiveMoney, 0, CMDT_MONEY_MANAGEMENT) diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 7e65b43ac2..66ef1a9898 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -440,11 +440,11 @@ struct CompanyFinancesWindow : Window { break; case WID_CF_INCREASE_LOAN: // increase loan - Command::Post(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY, 0, 0, _ctrl_pressed, {}); + Command::Post(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY, _ctrl_pressed ? LoanCommand::Max : LoanCommand::Interval, 0); break; case WID_CF_REPAY_LOAN: // repay loan - Command::Post(STR_ERROR_CAN_T_REPAY_LOAN, 0, 0, _ctrl_pressed, {}); + Command::Post(STR_ERROR_CAN_T_REPAY_LOAN, _ctrl_pressed ? LoanCommand::Max : LoanCommand::Interval, 0); break; case WID_CF_INFRASTRUCTURE: // show infrastructure details @@ -1000,7 +1000,7 @@ public: for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) { /* Changed colour for the selected scheme, or all visible schemes if CTRL is pressed. */ if (HasBit(this->sel, scheme) || (_ctrl_pressed && _livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme))) { - Command::Post(0, scheme | (widget == WID_SCL_PRI_COL_DROPDOWN ? 0 : 256), index, {}); + Command::Post(scheme, widget == WID_SCL_PRI_COL_DROPDOWN, (Colours)index); } } } else { @@ -1586,7 +1586,7 @@ public: /* OK button */ case WID_SCMF_ACCEPT: - Command::Post(0, 0, this->face, {}); + Command::Post(this->face); FALLTHROUGH; /* Cancel button */ @@ -2581,11 +2581,11 @@ struct CompanyWindow : Window break; case WID_C_BUY_SHARE: - Command::Post(STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, 0, this->window_number, 0, {}); + Command::Post(STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS, (CompanyID)this->window_number); break; case WID_C_SELL_SHARE: - Command::Post(STR_ERROR_CAN_T_SELL_25_SHARE_IN, 0, this->window_number, 0, {}); + Command::Post(STR_ERROR_CAN_T_SELL_25_SHARE_IN, (CompanyID)this->window_number); break; case WID_C_COMPANY_PASSWORD: @@ -2640,16 +2640,16 @@ struct CompanyWindow : Window Money money = (Money)(strtoull(str, nullptr, 10) / _currency->rate); uint32 money_c = Clamp(ClampToI32(money), 0, 20000000); // Clamp between 20 million and 0 - Command::Post(STR_ERROR_CAN_T_GIVE_MONEY, 0, money_c, this->window_number, {}); + Command::Post(STR_ERROR_CAN_T_GIVE_MONEY, money_c, (CompanyID)this->window_number); break; } case WID_C_PRESIDENT_NAME: - Command::Post(STR_ERROR_CAN_T_CHANGE_PRESIDENT, 0, 0, 0, str); + Command::Post(STR_ERROR_CAN_T_CHANGE_PRESIDENT, str); break; case WID_C_COMPANY_NAME: - Command::Post(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME, 0, 0, 0, str); + Command::Post(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME, str); break; case WID_C_COMPANY_JOIN: @@ -2776,7 +2776,7 @@ struct BuyCompanyWindow : Window { break; case WID_BC_YES: - Command::Post(STR_ERROR_CAN_T_BUY_COMPANY, 0, this->window_number, 0, {}); + Command::Post(STR_ERROR_CAN_T_BUY_COMPANY, (CompanyID)this->window_number); break; } } diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 9e244dd439..7f663fe863 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -632,7 +632,7 @@ DEF_CONSOLE_CMD(ConPauseGame) } if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - Command::Post(0, PM_PAUSED_NORMAL, 1, {}); + Command::Post(PM_PAUSED_NORMAL, true); if (!_networking) IConsolePrint(CC_DEFAULT, "Game paused."); } else { IConsolePrint(CC_DEFAULT, "Game is already paused."); @@ -654,7 +654,7 @@ DEF_CONSOLE_CMD(ConUnpauseGame) } if ((_pause_mode & PM_PAUSED_NORMAL) != PM_UNPAUSED) { - Command::Post(0, PM_PAUSED_NORMAL, 0, {}); + Command::Post(PM_PAUSED_NORMAL, false); if (!_networking) IConsolePrint(CC_DEFAULT, "Game unpaused."); } else if ((_pause_mode & PM_PAUSED_ERROR) != PM_UNPAUSED) { IConsolePrint(CC_DEFAULT, "Game is in error state and cannot be unpaused via console."); diff --git a/src/core/overflowsafe_type.hpp b/src/core/overflowsafe_type.hpp index 29aab175b3..14f0eaa7a7 100644 --- a/src/core/overflowsafe_type.hpp +++ b/src/core/overflowsafe_type.hpp @@ -39,9 +39,10 @@ public: constexpr OverflowSafeInt() : m_value(0) { } constexpr OverflowSafeInt(const OverflowSafeInt& other) : m_value(other.m_value) { } - constexpr OverflowSafeInt(const int64 int_) : m_value(int_) { } + constexpr OverflowSafeInt(const T int_) : m_value(int_) { } inline constexpr OverflowSafeInt& operator = (const OverflowSafeInt& other) { this->m_value = other.m_value; return *this; } + inline constexpr OverflowSafeInt& operator = (T other) { this->m_value = other; return *this; } inline constexpr OverflowSafeInt operator - () const { return OverflowSafeInt(this->m_value == T_MIN ? T_MAX : -this->m_value); } @@ -174,7 +175,7 @@ public: inline constexpr bool operator < (const int other) const { return !(*this >= other); } inline constexpr bool operator <= (const int other) const { return !(*this > other); } - inline constexpr operator int64 () const { return this->m_value; } + inline constexpr operator T () const { return this->m_value; } }; diff --git a/src/economy.cpp b/src/economy.cpp index 5c7c2cee51..6fb3d2795d 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -315,7 +315,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) for (i = 0; i < 4; i++) { if (c->share_owners[i] == old_owner) { /* Sell its shares */ - CommandCost res = Command::Do(DC_EXEC | DC_BANKRUPT, 0, c->index, 0, {}); + CommandCost res = Command::Do(DC_EXEC | DC_BANKRUPT, c->index); /* Because we are in a DoCommand, we can't just execute another one and * expect the money to be removed. We need to do it ourself! */ SubtractMoneyFromCompany(res); @@ -335,7 +335,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } else { cur_company2.Change(c->share_owners[i]); /* Sell the shares */ - CommandCost res = Command::Do(DC_EXEC | DC_BANKRUPT, 0, old_owner, 0, {}); + CommandCost res = Command::Do(DC_EXEC | DC_BANKRUPT, old_owner); /* Because we are in a DoCommand, we can't just execute another one and * expect the money to be removed. We need to do it ourself! */ SubtractMoneyFromCompany(res); @@ -2013,16 +2013,12 @@ extern int GetAmountOwnedBy(const Company *c, Owner owner); /** * Acquire shares in an opposing company. * @param flags type of operation - * @param tile unused * @param p1 company to buy the shares from - * @param p2 unused - * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuyShareInCompany(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuyShareInCompany(DoCommandFlag flags, TileIndex tile, CompanyID target_company) { CommandCost cost(EXPENSES_OTHER); - CompanyID target_company = (CompanyID)p1; Company *c = Company::GetIfValid(target_company); /* Check if buying shares is allowed (protection against modified clients) @@ -2065,15 +2061,11 @@ CommandCost CmdBuyShareInCompany(DoCommandFlag flags, TileIndex tile, uint32 p1, /** * Sell shares in an opposing company. * @param flags type of operation - * @param tile unused - * @param p1 company to sell the shares from - * @param p2 unused - * @param text unused + * @param target_company company to sell the shares from * @return the cost of this operation or an error */ -CommandCost CmdSellShareInCompany(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSellShareInCompany(DoCommandFlag flags, CompanyID target_company) { - CompanyID target_company = (CompanyID)p1; Company *c = Company::GetIfValid(target_company); /* Cannot sell own shares */ @@ -2106,15 +2098,11 @@ CommandCost CmdSellShareInCompany(DoCommandFlag flags, TileIndex tile, uint32 p1 * that company. * @todo currently this only works for AI companies * @param flags type of operation - * @param tile unused - * @param p1 company to buy up - * @param p2 unused - * @param text unused + * @param target_company company to buy up * @return the cost of this operation or an error */ -CommandCost CmdBuyCompany(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdBuyCompany(DoCommandFlag flags, CompanyID target_company) { - CompanyID target_company = (CompanyID)p1; Company *c = Company::GetIfValid(target_company); if (c == nullptr) return CMD_ERROR; diff --git a/src/economy_cmd.h b/src/economy_cmd.h index f182af81f2..e5cc282c99 100644 --- a/src/economy_cmd.h +++ b/src/economy_cmd.h @@ -11,10 +11,11 @@ #define ECONOMY_CMD_H #include "command_type.h" +#include "company_type.h" -CommandProc CmdBuyShareInCompany; -CommandProc CmdSellShareInCompany; -CommandProc CmdBuyCompany; +CommandCost CmdBuyShareInCompany(DoCommandFlag flags, TileIndex tile, CompanyID target_company); +CommandCost CmdSellShareInCompany(DoCommandFlag flags, CompanyID target_company); +CommandCost CmdBuyCompany(DoCommandFlag flags, CompanyID target_company); DEF_CMD_TRAIT(CMD_BUY_SHARE_IN_COMPANY, CmdBuyShareInCompany, 0, CMDT_MONEY_MANAGEMENT) DEF_CMD_TRAIT(CMD_SELL_SHARE_IN_COMPANY, CmdSellShareInCompany, 0, CMDT_MONEY_MANAGEMENT) diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 73315edf0f..3014bc00ec 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -359,7 +359,7 @@ public: /* pause is only used in single-player, non-editor mode, non-menu mode. It * will be unpaused in the WE_DESTROY event handler. */ if (_game_mode != GM_MENU && !_networking && _game_mode != GM_EDITOR) { - Command::Post(0, PM_PAUSED_SAVELOAD, 1, {}); + Command::Post(PM_PAUSED_SAVELOAD, true); } SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); @@ -403,7 +403,7 @@ public: { /* pause is only used in single-player, non-editor mode, non menu mode */ if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) { - Command::Post(0, PM_PAUSED_SAVELOAD, 0, {}); + Command::Post(PM_PAUSED_SAVELOAD, false); } this->Window::Close(); } diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index bf09b1b949..0ccc288f05 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -97,7 +97,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { EndGameWindow(WindowDesc *desc) : EndGameHighScoreBaseWindow(desc) { /* Pause in single-player to have a look at the highscore at your own leisure */ - if (!_networking) Command::Post(0, PM_PAUSED_NORMAL, 1, {}); + if (!_networking) Command::Post(PM_PAUSED_NORMAL, true); this->background_img = SPR_TYCOON_IMG1_BEGIN; @@ -125,7 +125,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { void Close() override { - if (!_networking) Command::Post(0, PM_PAUSED_NORMAL, 0, {}); // unpause + if (!_networking) Command::Post(PM_PAUSED_NORMAL, false); // unpause ShowHighscoreTable(this->window_number, this->rank); this->EndGameHighScoreBaseWindow::Close(); } @@ -160,7 +160,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { { /* pause game to show the chart */ this->game_paused_by_player = _pause_mode == PM_PAUSED_NORMAL; - if (!_networking && !this->game_paused_by_player) Command::Post(0, PM_PAUSED_NORMAL, 1, {}); + if (!_networking && !this->game_paused_by_player) Command::Post(PM_PAUSED_NORMAL, true); /* Close all always on-top windows to get a clean screen */ if (_game_mode != GM_MENU) HideVitalWindows(); @@ -175,7 +175,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { { if (_game_mode != GM_MENU) ShowVitalWindows(); - if (!_networking && !this->game_paused_by_player) Command::Post(0, PM_PAUSED_NORMAL, 0, {}); // unpause + if (!_networking && !this->game_paused_by_player) Command::Post(PM_PAUSED_NORMAL, false); // unpause this->EndGameHighScoreBaseWindow::Close(); } diff --git a/src/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index 0a6b891502..3581c72ac9 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.cpp @@ -174,7 +174,7 @@ void StateGameLoop_LinkGraphPauseControl() if (_pause_mode & PM_PAUSED_LINK_GRAPH) { /* We are paused waiting on a job, check the job every tick. */ if (!LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { - Command::Post(0, PM_PAUSED_LINK_GRAPH, 0, {}); + Command::Post(PM_PAUSED_LINK_GRAPH, false); } } else if (_pause_mode == PM_UNPAUSED && _date_fract == LinkGraphSchedule::SPAWN_JOIN_TICK - 2 && @@ -182,7 +182,7 @@ void StateGameLoop_LinkGraphPauseControl() LinkGraphSchedule::instance.IsJoinWithUnfinishedJobDue()) { /* Perform check two _date_fract ticks before we would join, to make * sure it also works in multiplayer. */ - Command::Post(0, PM_PAUSED_LINK_GRAPH, 1, {}); + Command::Post(PM_PAUSED_LINK_GRAPH, true); } } diff --git a/src/livery.h b/src/livery.h index dc01c390a7..352cf6972e 100644 --- a/src/livery.h +++ b/src/livery.h @@ -17,7 +17,7 @@ static const byte LIT_COMPANY = 1; ///< Show the liveries of your own company static const byte LIT_ALL = 2; ///< Show the liveries of all companies /** List of different livery schemes. */ -enum LiveryScheme { +enum LiveryScheme : byte { LS_BEGIN = 0, LS_DEFAULT = 0, diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 680493c12c..c25186164a 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -327,7 +327,7 @@ struct MainWindow : Window case GHK_MONEY: // Gimme money /* You can only cheat for money in singleplayer mode. */ - if (!_networking) Command::Post(0, 10000000, 0, {}); + if (!_networking) Command::Post(10000000); break; case GHK_UPDATE_COORDS: // Update the coordinates of all station signs diff --git a/src/misc/endian_buffer.hpp b/src/misc/endian_buffer.hpp index c20d9a8b99..87d527d9d8 100644 --- a/src/misc/endian_buffer.hpp +++ b/src/misc/endian_buffer.hpp @@ -14,6 +14,7 @@ #include #include "../core/span_type.hpp" #include "../core/bitmath_func.hpp" +#include "../core/overflowsafe_type.hpp" struct StrongTypedefBase; @@ -37,6 +38,9 @@ public: EndianBufferWriter &operator <<(std::string_view data) { this->Write(data); return *this; } EndianBufferWriter &operator <<(bool data) { return *this << static_cast(data ? 1 : 0); } + template + EndianBufferWriter &operator <<(const OverflowSafeInt &data) { return *this << static_cast(data); }; + template EndianBufferWriter &operator <<(const std::tuple &data) { @@ -127,6 +131,9 @@ public: EndianBufferReader &operator >>(std::string &data) { data = this->ReadStr(); return *this; } EndianBufferReader &operator >>(bool &data) { data = this->Read() != 0; return *this; } + template + EndianBufferReader &operator >>(OverflowSafeInt &data) { data = this->Read(); return *this; }; + template EndianBufferReader &operator >>(std::tuple &data) { diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index 84c61e3f18..fd8f79476e 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -28,22 +28,16 @@ #include "safeguards.h" -/* Make sure we can discard lower 2 bits of 64bit amount when passing it to Cmd[In|De]creaseLoan() */ -static_assert((LOAN_INTERVAL & 3) == 0); - /** * Increase the loan of your company. * @param flags operation to perform - * @param tile unused - * @param p1 higher half of amount to increase the loan with, multitude of LOAN_INTERVAL. Only used when (p2 & 3) == 2. - * @param p2 (bit 2-31) - lower half of amount (lower 2 bits assumed to be 0) - * (bit 0-1) - when 0: loans LOAN_INTERVAL - * when 1: loans the maximum loan permitting money (press CTRL), - * when 2: loans the amount specified in p1 and p2 - * @param text unused + * @param cmd when LoanCommand::Interval: loans LOAN_INTERVAL, + * when LoanCommand::Max: loans the maximum loan permitting money (press CTRL), + * when LoanCommand::Amount: loans the amount specified in \c amount + * @param amount amount to increase the loan with, multitude of LOAN_INTERVAL. Only used when cmd == LoanCommand::Amount. * @return the cost of this operation or an error */ -CommandCost CmdIncreaseLoan(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdIncreaseLoan(DoCommandFlag flags, LoanCommand cmd, Money amount) { Company *c = Company::Get(_current_company); @@ -53,16 +47,16 @@ CommandCost CmdIncreaseLoan(DoCommandFlag flags, TileIndex tile, uint32 p1, uint } Money loan; - switch (p2 & 3) { + switch (cmd) { default: return CMD_ERROR; // Invalid method - case 0: // Take some extra loan + case LoanCommand::Interval: // Take some extra loan loan = LOAN_INTERVAL; break; - case 1: // Take a loan as big as possible + case LoanCommand::Max: // Take a loan as big as possible loan = _economy.max_loan - c->current_loan; break; - case 2: // Take the given amount of loan - loan = ((uint64)p1 << 32) | (p2 & 0xFFFFFFFC); + case LoanCommand::Amount: // Take the given amount of loan + loan = amount; if (loan < LOAN_INTERVAL || c->current_loan + loan > _economy.max_loan || loan % LOAN_INTERVAL != 0) return CMD_ERROR; break; } @@ -82,33 +76,30 @@ CommandCost CmdIncreaseLoan(DoCommandFlag flags, TileIndex tile, uint32 p1, uint /** * Decrease the loan of your company. * @param flags operation to perform - * @param tile unused - * @param p1 higher half of amount to decrease the loan with, multitude of LOAN_INTERVAL. Only used when (p2 & 3) == 2. - * @param p2 (bit 2-31) - lower half of amount (lower 2 bits assumed to be 0) - * (bit 0-1) - when 0: pays back LOAN_INTERVAL - * when 1: pays back the maximum loan permitting money (press CTRL), - * when 2: pays back the amount specified in p1 and p2 - * @param text unused + * @param cmd when LoanCommand::Interval: pays back LOAN_INTERVAL, + * when LoanCommand::Max: pays back the maximum loan permitting money (press CTRL), + * when LoanCommand::Amount: pays back the amount specified in \c amount + * @param amount amount to decrease the loan with, multitude of LOAN_INTERVAL. Only used when cmd == LoanCommand::Amount. * @return the cost of this operation or an error */ -CommandCost CmdDecreaseLoan(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdDecreaseLoan(DoCommandFlag flags, LoanCommand cmd, Money amount) { Company *c = Company::Get(_current_company); if (c->current_loan == 0) return_cmd_error(STR_ERROR_LOAN_ALREADY_REPAYED); Money loan; - switch (p2 & 3) { + switch (cmd) { default: return CMD_ERROR; // Invalid method - case 0: // Pay back one step + case LoanCommand::Interval: // Pay back one step loan = std::min(c->current_loan, (Money)LOAN_INTERVAL); break; - case 1: // Pay back as much as possible + case LoanCommand::Max: // Pay back as much as possible loan = std::max(std::min(c->current_loan, c->money), (Money)LOAN_INTERVAL); loan -= loan % LOAN_INTERVAL; break; - case 2: // Repay the given amount of loan - loan = ((uint64)p1 << 32) | (p2 & 0xFFFFFFFC); + case LoanCommand::Amount: // Repay the given amount of loan + loan = amount; if (loan % LOAN_INTERVAL != 0 || loan < LOAN_INTERVAL || loan > c->current_loan) return CMD_ERROR; // Invalid amount to loan break; } @@ -135,7 +126,7 @@ CommandCost CmdDecreaseLoan(DoCommandFlag flags, TileIndex tile, uint32 p1, uint static void AskUnsafeUnpauseCallback(Window *w, bool confirmed) { if (confirmed) { - Command::Post(0, PM_PAUSED_ERROR, 0, {}); + Command::Post(PM_PAUSED_ERROR, false); } } @@ -145,15 +136,13 @@ static void AskUnsafeUnpauseCallback(Window *w, bool confirmed) * unpaused. A bitset is used instead of a boolean value/counter to have * more control over the game when saving/loading, etc. * @param flags operation to perform - * @param tile unused - * @param p1 the pause mode to change - * @param p2 1 pauses, 0 unpauses this mode - * @param text unused + * @param mode the pause mode to change + * @param pause true pauses, false unpauses this mode * @return the cost of this operation or an error */ -CommandCost CmdPause(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdPause(DoCommandFlag flags, PauseMode mode, bool pause) { - switch (p1) { + switch (mode) { case PM_PAUSED_SAVELOAD: case PM_PAUSED_ERROR: case PM_PAUSED_NORMAL: @@ -169,7 +158,7 @@ CommandCost CmdPause(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, default: return CMD_ERROR; } if (flags & DC_EXEC) { - if (p1 == PM_PAUSED_NORMAL && _pause_mode & PM_PAUSED_ERROR) { + if (mode == PM_PAUSED_NORMAL && _pause_mode & PM_PAUSED_ERROR) { ShowQuery( STR_NEWGRF_UNPAUSE_WARNING_TITLE, STR_NEWGRF_UNPAUSE_WARNING, @@ -179,13 +168,13 @@ CommandCost CmdPause(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, } else { PauseMode prev_mode = _pause_mode; - if (p2 == 0) { - _pause_mode = static_cast(_pause_mode & (byte)~p1); + if (pause) { + _pause_mode |= mode; } else { - _pause_mode = static_cast(_pause_mode | (byte)p1); + _pause_mode &= ~mode; } - NetworkHandlePauseChange(prev_mode, (PauseMode)p1); + NetworkHandlePauseChange(prev_mode, mode); } SetWindowDirty(WC_STATUS_BAR, 0); @@ -197,33 +186,25 @@ CommandCost CmdPause(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, /** * Change the financial flow of your company. * @param flags operation to perform - * @param tile unused - * @param p1 the amount of money to receive (if positive), or spend (if negative) - * @param p2 unused - * @param text unused + * @param amount the amount of money to receive (if positive), or spend (if negative) * @return the cost of this operation or an error */ -CommandCost CmdMoneyCheat(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdMoneyCheat(DoCommandFlag flags, Money amount) { - return CommandCost(EXPENSES_OTHER, -(int32)p1); + return CommandCost(EXPENSES_OTHER, -amount); } /** * Change the bank bank balance of a company by inserting or removing money without affecting the loan. * @param flags operation to perform * @param tile tile to show text effect on (if not 0) - * @param p1 the amount of money to receive (if positive), or spend (if negative) - * @param p2 (bit 0-7) - the company ID. - * (bit 8-15) - the expenses type which should register the cost/income @see ExpensesType. - * @param text unused + * @param delta the amount of money to receive (if positive), or spend (if negative) + * @param company the company ID. + * @param expenses_type the expenses type which should register the cost/income @see ExpensesType. * @return zero cost or an error */ -CommandCost CmdChangeBankBalance(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeBankBalance(DoCommandFlag flags, TileIndex tile, Money delta, CompanyID company, ExpensesType expenses_type) { - int32 delta = (int32)p1; - CompanyID company = (CompanyID) GB(p2, 0, 8); - ExpensesType expenses_type = Extract(p2); - if (!Company::IsValidID(company)) return CMD_ERROR; if (expenses_type >= EXPENSES_END) return CMD_ERROR; if (_current_company != OWNER_DEITY) return CMD_ERROR; diff --git a/src/misc_cmd.h b/src/misc_cmd.h index 6827db3ac2..77250b551c 100644 --- a/src/misc_cmd.h +++ b/src/misc_cmd.h @@ -11,12 +11,21 @@ #define MISC_CMD_H #include "command_type.h" +#include "economy_type.h" -CommandProc CmdMoneyCheat; -CommandProc CmdChangeBankBalance; -CommandProc CmdIncreaseLoan; -CommandProc CmdDecreaseLoan; -CommandProc CmdPause; +enum PauseMode : byte; + +enum class LoanCommand : byte { + Interval, + Max, + Amount, +}; + +CommandCost CmdMoneyCheat(DoCommandFlag flags, Money amount); +CommandCost CmdChangeBankBalance(DoCommandFlag flags, TileIndex tile, Money delta, CompanyID company, ExpensesType expenses_type); +CommandCost CmdIncreaseLoan(DoCommandFlag flags, LoanCommand cmd, Money amount); +CommandCost CmdDecreaseLoan(DoCommandFlag flags, LoanCommand cmd, Money amount); +CommandCost CmdPause(DoCommandFlag flags, PauseMode mode, bool pause); DEF_CMD_TRAIT(CMD_MONEY_CHEAT, CmdMoneyCheat, CMD_OFFLINE, CMDT_CHEAT) DEF_CMD_TRAIT(CMD_CHANGE_BANK_BALANCE, CmdChangeBankBalance, CMD_DEITY, CMDT_MONEY_MANAGEMENT) diff --git a/src/network/network.cpp b/src/network/network.cpp index 3bd287f85a..19cb6ab3a4 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -395,7 +395,7 @@ static void CheckPauseHelper(bool pause, PauseMode pm) { if (pause == ((_pause_mode & pm) != PM_UNPAUSED)) return; - Command::Post(0, pm, pause ? 1 : 0, {}); + Command::Post(pm, pause); } /** @@ -1128,7 +1128,7 @@ void NetworkGameLoop() cp = new CommandPacket(); cp->company = COMPANY_SPECTATOR; cp->cmd = CMD_PAUSE; - cp->data = EndianBufferWriter<>::FromValue(CommandTraits::Args{ 0, PM_PAUSED_NORMAL, 1, "" }); + cp->data = EndianBufferWriter<>::FromValue(CommandTraits::Args{ PM_PAUSED_NORMAL, true }); _ddc_fastforward = false; } else if (strncmp(p, "sync: ", 6) == 0) { int ret = sscanf(p + 6, "%x; %x; %x; %x", &next_date, &next_date_fract, &sync_state[0], &sync_state[1]); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 197d398bf6..36ab3840a4 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -2081,7 +2081,7 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci) /* ci is nullptr when replaying, or for AIs. In neither case there is a client. */ ci->client_playas = c->index; NetworkUpdateClientInfo(ci->client_id); - Command::SendNet(STR_NULL, nullptr, c->index, 0, 0, 0, ci->client_name); + Command::SendNet(STR_NULL, nullptr, c->index, ci->client_name); } /* Announce new company on network. */ diff --git a/src/news_cmd.h b/src/news_cmd.h index 4a75037b3b..6ebb1b84d9 100644 --- a/src/news_cmd.h +++ b/src/news_cmd.h @@ -11,8 +11,10 @@ #define NEWS_CMD_H #include "command_type.h" +#include "company_type.h" +#include "news_type.h" -CommandProc CmdCustomNewsItem; +CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceType reftype1, CompanyID company, uint32 reference, const std::string &text); DEF_CMD_TRAIT(CMD_CUSTOM_NEWS_ITEM, CmdCustomNewsItem, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT) diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 69ab19b3b4..ee0e17fac0 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -837,23 +837,17 @@ void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceTy /** * Create a new custom news item. * @param flags type of operation - * @param tile unused - * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 7) - NewsType of the message. - * - p1 = (bit 8 - 15) - NewsReferenceType of first reference. - * - p1 = (bit 16 - 23) - Company this news message is for. - * @param p2 First reference of the news message. + * @aram type NewsType of the message. + * @param reftype1 NewsReferenceType of first reference. + * @param company Company this news message is for. + * @param reference First reference of the news message. * @param text The text of the news message. * @return the cost of this operation or an error */ -CommandCost CmdCustomNewsItem(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCustomNewsItem(DoCommandFlag flags, NewsType type, NewsReferenceType reftype1, CompanyID company, uint32 reference, const std::string &text) { if (_current_company != OWNER_DEITY) return CMD_ERROR; - NewsType type = (NewsType)GB(p1, 0, 8); - NewsReferenceType reftype1 = (NewsReferenceType)GB(p1, 8, 8); - CompanyID company = (CompanyID)GB(p1, 16, 8); - if (company != INVALID_OWNER && !Company::IsValidID(company)) return CMD_ERROR; if (type >= NT_END) return CMD_ERROR; if (text.empty()) return CMD_ERROR; @@ -861,27 +855,27 @@ CommandCost CmdCustomNewsItem(DoCommandFlag flags, TileIndex tile, uint32 p1, ui switch (reftype1) { case NR_NONE: break; case NR_TILE: - if (!IsValidTile(p2)) return CMD_ERROR; + if (!IsValidTile(reference)) return CMD_ERROR; break; case NR_VEHICLE: - if (!Vehicle::IsValidID(p2)) return CMD_ERROR; + if (!Vehicle::IsValidID(reference)) return CMD_ERROR; break; case NR_STATION: - if (!Station::IsValidID(p2)) return CMD_ERROR; + if (!Station::IsValidID(reference)) return CMD_ERROR; break; case NR_INDUSTRY: - if (!Industry::IsValidID(p2)) return CMD_ERROR; + if (!Industry::IsValidID(reference)) return CMD_ERROR; break; case NR_TOWN: - if (!Town::IsValidID(p2)) return CMD_ERROR; + if (!Town::IsValidID(reference)) return CMD_ERROR; break; case NR_ENGINE: - if (!Engine::IsValidID(p2)) return CMD_ERROR; + if (!Engine::IsValidID(reference)) return CMD_ERROR; break; default: return CMD_ERROR; @@ -892,7 +886,7 @@ CommandCost CmdCustomNewsItem(DoCommandFlag flags, TileIndex tile, uint32 p1, ui if (flags & DC_EXEC) { NewsStringData *news = new NewsStringData(text); SetDParamStr(0, news->string); - AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, p2, NR_NONE, UINT32_MAX, news); + AddNewsItem(STR_NEWS_CUSTOM_ITEM, type, NF_NORMAL, reftype1, reference, NR_NONE, UINT32_MAX, news); } return CommandCost(); diff --git a/src/news_type.h b/src/news_type.h index 188305b52f..7d9f6b7720 100644 --- a/src/news_type.h +++ b/src/news_type.h @@ -18,7 +18,7 @@ /** * Type of news. */ -enum NewsType { +enum NewsType : byte { NT_ARRIVAL_COMPANY, ///< First vehicle arrived for company NT_ARRIVAL_OTHER, ///< First vehicle arrived for competitor NT_ACCIDENT, ///< An accident or disaster has occurred @@ -47,7 +47,7 @@ enum NewsType { * You have to make sure, #ChangeVehicleNews catches the DParams of your message. * This is NOT ensured by the references. */ -enum NewsReferenceType { +enum NewsReferenceType : byte { NR_NONE, ///< Empty reference NR_TILE, ///< Reference tile. Scroll to tile when clicking on the news. NR_VEHICLE, ///< Reference vehicle. Scroll to vehicle when clicking on the news. Delete news when vehicle is deleted. diff --git a/src/openttd.cpp b/src/openttd.cpp index c5c849e71c..230529a786 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -852,7 +852,7 @@ static void MakeNewGameDone() /* In a dedicated server, the server does not play */ if (!VideoDriver::GetInstance()->HasGUI()) { OnStartGame(true); - if (_settings_client.gui.pause_on_newgame) Command::Post(0, PM_PAUSED_NORMAL, 1, {}); + if (_settings_client.gui.pause_on_newgame) Command::Post(PM_PAUSED_NORMAL, true); return; } @@ -881,7 +881,7 @@ static void MakeNewGameDone() NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass); } - if (_settings_client.gui.pause_on_newgame) Command::Post(0, PM_PAUSED_NORMAL, 1, {}); + if (_settings_client.gui.pause_on_newgame) Command::Post(PM_PAUSED_NORMAL, true); CheckEngines(); CheckIndustries(); @@ -1046,7 +1046,7 @@ void SwitchToMode(SwitchMode new_mode) } OnStartGame(_network_dedicated); /* Decrease pause counter (was increased from opening load dialog) */ - Command::Post(0, PM_PAUSED_SAVELOAD, 0, {}); + Command::Post(PM_PAUSED_SAVELOAD, false); } break; } @@ -1068,7 +1068,7 @@ void SwitchToMode(SwitchMode new_mode) SetLocalCompany(OWNER_NONE); _settings_newgame.game_creation.starting_year = _cur_year; /* Cancel the saveload pausing */ - Command::Post(0, PM_PAUSED_SAVELOAD, 0, {}); + Command::Post(PM_PAUSED_SAVELOAD, false); } else { SetDParamStr(0, GetSaveLoadErrorString()); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); diff --git a/src/script/api/script_company.cpp b/src/script/api/script_company.cpp index 1cc69bc93f..6a06852da5 100644 --- a/src/script/api/script_company.cpp +++ b/src/script/api/script_company.cpp @@ -52,7 +52,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_COMPANY_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::Command::Do(0, 0, 0, text); + return ScriptObject::Command::Do(text); } /* static */ char *ScriptCompany::GetName(ScriptCompany::CompanyID company) @@ -73,7 +73,7 @@ EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_PRESIDENT_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); - return ScriptObject::Command::Do(0, 0, 0, text); + return ScriptObject::Command::Do(text); } /* static */ char *ScriptCompany::GetPresidentName(ScriptCompany::CompanyID company) @@ -101,7 +101,7 @@ GenderEthnicity ge = (GenderEthnicity)((gender == GENDER_FEMALE ? (1 << ::GENDER_FEMALE) : 0) | (::InteractiveRandom() & (1 << ETHNICITY_BLACK))); RandomCompanyManagerFaceBits(cmf, ge, false); - return ScriptObject::Command::Do(0, 0, cmf, {}); + return ScriptObject::Command::Do(cmf); } /* static */ ScriptCompany::Gender ScriptCompany::GetPresidentGender(CompanyID company) @@ -211,9 +211,9 @@ Money amount = abs(loan - GetLoanAmount()); if (loan > GetLoanAmount()) { - return ScriptObject::Command::Do(0, amount >> 32, (amount & 0xFFFFFFFC) | 2, {}); + return ScriptObject::Command::Do(LoanCommand::Amount, amount); } else { - return ScriptObject::Command::Do(0, amount >> 32, (amount & 0xFFFFFFFC) | 2, {}); + return ScriptObject::Command::Do(LoanCommand::Amount, amount); } } @@ -244,7 +244,7 @@ EnforcePrecondition(false, company != COMPANY_INVALID); /* Network commands only allow 0 to indicate invalid tiles, not INVALID_TILE */ - return ScriptObject::Command::Do(tile == INVALID_TILE ? (TileIndex)0U : tile, (uint32)(delta), company | expenses_type << 8, {}); + return ScriptObject::Command::Do(tile == INVALID_TILE ? (TileIndex)0U : tile, delta, (::CompanyID)company, (::ExpensesType)expenses_type); } /* static */ bool ScriptCompany::BuildCompanyHQ(TileIndex tile) @@ -266,7 +266,7 @@ /* static */ bool ScriptCompany::SetAutoRenewStatus(bool autorenew) { - return ScriptObject::Command::Do(0, 0, autorenew ? 1 : 0, "company.engine_renew"); + return ScriptObject::Command::Do("company.engine_renew", autorenew ? 1 : 0); } /* static */ bool ScriptCompany::GetAutoRenewStatus(CompanyID company) @@ -279,7 +279,7 @@ /* static */ bool ScriptCompany::SetAutoRenewMonths(int16 months) { - return ScriptObject::Command::Do(0, 0, months, "company.engine_renew_months"); + return ScriptObject::Command::Do("company.engine_renew_months", months); } /* static */ int16 ScriptCompany::GetAutoRenewMonths(CompanyID company) @@ -294,7 +294,7 @@ { EnforcePrecondition(false, money >= 0); EnforcePrecondition(false, (int64)money <= UINT32_MAX); - return ScriptObject::Command::Do(0, 0, money, "company.engine_renew_money"); + return ScriptObject::Command::Do("company.engine_renew_money", money); } /* static */ Money ScriptCompany::GetAutoRenewMoney(CompanyID company) @@ -307,12 +307,12 @@ /* static */ bool ScriptCompany::SetPrimaryLiveryColour(LiveryScheme scheme, Colours colour) { - return ScriptObject::Command::Do(0, scheme, colour, {}); + return ScriptObject::Command::Do((::LiveryScheme)scheme, true, (::Colours)colour); } /* static */ bool ScriptCompany::SetSecondaryLiveryColour(LiveryScheme scheme, Colours colour) { - return ScriptObject::Command::Do(0, scheme | 1 << 8, colour, {}); + return ScriptObject::Command::Do((::LiveryScheme)scheme, false, (::Colours)colour); } /* static */ ScriptCompany::Colours ScriptCompany::GetPrimaryLiveryColour(ScriptCompany::LiveryScheme scheme) diff --git a/src/script/api/script_controller.cpp b/src/script/api/script_controller.cpp index 74a3ad3ea8..232ce5a3b6 100644 --- a/src/script/api/script_controller.cpp +++ b/src/script/api/script_controller.cpp @@ -60,7 +60,7 @@ ShowAIDebugWindow(ScriptObject::GetRootCompany()); if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - ScriptObject::Command::Do(0, PM_PAUSED_NORMAL, 1, {}); + ScriptObject::Command::Do(PM_PAUSED_NORMAL, true); } } diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp index e876febc28..e9349a035f 100644 --- a/src/script/api/script_event_types.cpp +++ b/src/script/api/script_event_types.cpp @@ -117,7 +117,7 @@ bool ScriptEventEnginePreview::AcceptPreview() bool ScriptEventCompanyAskMerger::AcceptMerger() { - return ScriptObject::Command::Do(0, this->owner, 0, {}); + return ScriptObject::Command::Do((::CompanyID)this->owner); } ScriptEventAdminPort::ScriptEventAdminPort(const std::string &json) : diff --git a/src/script/api/script_game.cpp b/src/script/api/script_game.cpp index 9b40a1cd3b..3df6aef154 100644 --- a/src/script/api/script_game.cpp +++ b/src/script/api/script_game.cpp @@ -18,12 +18,12 @@ /* static */ bool ScriptGame::Pause() { - return ScriptObject::Command::Do(0, PM_PAUSED_GAME_SCRIPT, 1, {}); + return ScriptObject::Command::Do(PM_PAUSED_GAME_SCRIPT, true); } /* static */ bool ScriptGame::Unpause() { - return ScriptObject::Command::Do(0, PM_PAUSED_GAME_SCRIPT, 0, {}); + return ScriptObject::Command::Do(PM_PAUSED_GAME_SCRIPT, false); } /* static */ bool ScriptGame::IsPaused() diff --git a/src/script/api/script_gamesettings.cpp b/src/script/api/script_gamesettings.cpp index 611b78b8b6..2791aba006 100644 --- a/src/script/api/script_gamesettings.cpp +++ b/src/script/api/script_gamesettings.cpp @@ -38,7 +38,7 @@ if ((sd->flags & SF_NO_NETWORK_SYNC) != 0) return false; - return ScriptObject::Command::Do(0, 0, value, sd->GetName()); + return ScriptObject::Command::Do(sd->GetName(), value); } /* static */ bool ScriptGameSettings::IsDisabledVehicleType(ScriptVehicle::VehicleType vehicle_type) diff --git a/src/script/api/script_group.cpp b/src/script/api/script_group.cpp index 5047dc5c0e..dbf4c0280e 100644 --- a/src/script/api/script_group.cpp +++ b/src/script/api/script_group.cpp @@ -130,7 +130,7 @@ { if (HasWagonRemoval() == enable_removal) return true; - return ScriptObject::Command::Do(0, 0, enable_removal ? 1 : 0, "company.renew_keep_length"); + return ScriptObject::Command::Do("company.renew_keep_length", enable_removal ? 1 : 0); } /* static */ bool ScriptGroup::HasWagonRemoval() diff --git a/src/script/api/script_news.cpp b/src/script/api/script_news.cpp index 7f46f5aa6c..119cbc735c 100644 --- a/src/script/api/script_news.cpp +++ b/src/script/api/script_news.cpp @@ -39,5 +39,5 @@ if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; if (ref_type == NR_NONE) reference = 0; - return ScriptObject::Command::Do(0, type | (ref_type << 8) | (c << 16), reference, encoded); + return ScriptObject::Command::Do((::NewsType)type, (::NewsReferenceType)ref_type, (::CompanyID)c, reference, encoded); } diff --git a/src/script/api/script_subsidy.cpp b/src/script/api/script_subsidy.cpp index 32962d1581..5e1180d1bb 100644 --- a/src/script/api/script_subsidy.cpp +++ b/src/script/api/script_subsidy.cpp @@ -39,7 +39,7 @@ EnforcePrecondition(false, (from_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(from_id)) || (from_type == SPT_TOWN && ScriptTown::IsValidTown(from_id))); EnforcePrecondition(false, (to_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(to_id)) || (to_type == SPT_TOWN && ScriptTown::IsValidTown(to_id))); - return ScriptObject::Command::Do(0, from_type | (from_id << 8) | (cargo_type << 24), to_type | (to_id << 8), {}); + return ScriptObject::Command::Do(cargo_type, (::SourceType)from_type, from_id, (::SourceType)to_type, to_id); } /* static */ ScriptCompany::CompanyID ScriptSubsidy::GetAwardedTo(SubsidyID subsidy_id) diff --git a/src/settings.cpp b/src/settings.cpp index 3c0f92f39b..25eeb964a5 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1487,18 +1487,16 @@ const SettingDesc *GetSettingFromName(const std::string_view name) /** * Network-safe changing of settings (server-only). * @param flags operation to perform - * @param tile unused - * @param p1 unused - * @param p2 the new value for the setting + * @param name the name of the setting to change + * @param value the new value for the setting * The new value is properly clamped to its minimum/maximum when setting - * @param text the name of the setting to change * @return the cost of this operation or an error * @see _settings */ -CommandCost CmdChangeSetting(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeSetting(DoCommandFlag flags, const std::string &name, int32 value) { - if (text.empty()) return CMD_ERROR; - const SettingDesc *sd = GetSettingFromName(text); + if (name.empty()) return CMD_ERROR; + const SettingDesc *sd = GetSettingFromName(name); if (sd == nullptr) return CMD_ERROR; if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) return CMD_ERROR; @@ -1507,7 +1505,7 @@ CommandCost CmdChangeSetting(DoCommandFlag flags, TileIndex tile, uint32 p1, uin if (!sd->IsEditable(true)) return CMD_ERROR; if (flags & DC_EXEC) { - sd->AsIntSetting()->ChangeValue(&GetGameSettings(), p2); + sd->AsIntSetting()->ChangeValue(&GetGameSettings(), value); } return CommandCost(); @@ -1516,23 +1514,21 @@ CommandCost CmdChangeSetting(DoCommandFlag flags, TileIndex tile, uint32 p1, uin /** * Change one of the per-company settings. * @param flags operation to perform - * @param tile unused - * @param p1 unused - * @param p2 the new value for the setting + * @param name the name of the company setting to change + * @param value the new value for the setting * The new value is properly clamped to its minimum/maximum when setting - * @param text the name of the company setting to change * @return the cost of this operation or an error */ -CommandCost CmdChangeCompanySetting(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeCompanySetting(DoCommandFlag flags, const std::string &name, int32 value) { - if (text.empty()) return CMD_ERROR; - const SettingDesc *sd = GetCompanySettingFromName(text.c_str()); + if (name.empty()) return CMD_ERROR; + const SettingDesc *sd = GetCompanySettingFromName(name); if (sd == nullptr) return CMD_ERROR; if (!sd->IsIntSetting()) return CMD_ERROR; if (flags & DC_EXEC) { - sd->AsIntSetting()->ChangeValue(&Company::Get(_current_company)->settings, p2); + sd->AsIntSetting()->ChangeValue(&Company::Get(_current_company)->settings, value); } return CommandCost(); @@ -1550,7 +1546,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) const IntSettingDesc *setting = sd->AsIntSetting(); if ((setting->flags & SF_PER_COMPANY) != 0) { if (Company::IsValidID(_local_company) && _game_mode != GM_MENU) { - return Command::Post(0, 0, value, setting->GetName()); + return Command::Post(setting->GetName(), value); } setting->ChangeValue(&_settings_client.company, value); @@ -1576,7 +1572,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame) /* send non-company-based settings over the network */ if (!_networking || (_networking && _network_server)) { - return Command::Post(0, 0, value, setting->GetName()); + return Command::Post(setting->GetName(), value); } return false; } @@ -1604,7 +1600,7 @@ void SyncCompanySettings() const SettingDesc *sd = GetSettingDesc(desc); uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object); uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object); - if (old_value != new_value) Command::SendNet(STR_NULL, nullptr, _local_company, 0, 0, new_value, sd->GetName()); + if (old_value != new_value) Command::SendNet(STR_NULL, nullptr, _local_company, sd->GetName(), new_value); } } diff --git a/src/settings_cmd.h b/src/settings_cmd.h index 15b9c31a48..d41f229e1b 100644 --- a/src/settings_cmd.h +++ b/src/settings_cmd.h @@ -12,8 +12,8 @@ #include "command_type.h" -CommandProc CmdChangeSetting; -CommandProc CmdChangeCompanySetting; +CommandCost CmdChangeSetting(DoCommandFlag flags, const std::string &name, int32 value); +CommandCost CmdChangeCompanySetting(DoCommandFlag flags, const std::string &name, int32 value); DEF_CMD_TRAIT(CMD_CHANGE_SETTING, CmdChangeSetting, CMD_SERVER, CMDT_SERVER_SETTING) DEF_CMD_TRAIT(CMD_CHANGE_COMPANY_SETTING, CmdChangeCompanySetting, 0, CMDT_COMPANY_SETTING) diff --git a/src/subsidy.cpp b/src/subsidy.cpp index 992c7a6726..0c32dbcf12 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.cpp @@ -232,27 +232,17 @@ void CreateSubsidy(CargoID cid, SourceType src_type, SourceID src, SourceType ds /** * Create a new subsidy. * @param flags type of operation - * @param tile unused. - * @param p1 various bitstuffed elements - * - p1 = (bit 0 - 7) - SourceType of source. - * - p1 = (bit 8 - 23) - SourceID of source. - * - p1 = (bit 24 - 31) - CargoID of subsidy. - * @param p2 various bitstuffed elements - * - p2 = (bit 0 - 7) - SourceType of destination. - * - p2 = (bit 8 - 23) - SourceID of destination. - * @param text unused. + * @param cid CargoID of subsidy. + * @param src_type SourceType of source. + * @param src SourceID of source. + * @param dst_type SourceType of destination. + * @param dst SourceID of destination. * @return the cost of this operation or an error */ -CommandCost CmdCreateSubsidy(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdCreateSubsidy(DoCommandFlag flags, CargoID cid, SourceType src_type, SourceID src, SourceType dst_type, SourceID dst) { if (!Subsidy::CanAllocateItem()) return CMD_ERROR; - CargoID cid = GB(p1, 24, 8); - SourceType src_type = (SourceType)GB(p1, 0, 8); - SourceID src = GB(p1, 8, 16); - SourceType dst_type = (SourceType)GB(p2, 0, 8); - SourceID dst = GB(p2, 8, 16); - if (_current_company != OWNER_DEITY) return CMD_ERROR; if (cid >= NUM_CARGO || !::CargoSpec::Get(cid)->IsValid()) return CMD_ERROR; diff --git a/src/subsidy_cmd.h b/src/subsidy_cmd.h index f68c9b3034..d018688dad 100644 --- a/src/subsidy_cmd.h +++ b/src/subsidy_cmd.h @@ -11,8 +11,9 @@ #define SUBSIDY_CMD_H #include "command_type.h" +#include "cargo_type.h" -CommandProc CmdCreateSubsidy; +CommandCost CmdCreateSubsidy(DoCommandFlag flags, CargoID cid, SourceType src_type, SourceID src, SourceType dst_type, SourceID dst); DEF_CMD_TRAIT(CMD_CREATE_SUBSIDY, CmdCreateSubsidy, CMD_DEITY, CMDT_OTHER_MANAGEMENT) diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index b2b25afa6c..13c52f2b4e 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -266,7 +266,7 @@ static CallBackFunction ToolbarPauseClick(Window *w) { if (_networking && !_network_server) return CBF_NONE; // only server can pause the game - if (Command::Post(0, PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED, {})) { + if (Command::Post(PM_PAUSED_NORMAL, _pause_mode == PM_UNPAUSED)) { if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); } return CBF_NONE; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 8bfc332f65..6bb8d0986a 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -88,7 +88,7 @@ void CheckTrainsLengths() if (!_networking && first) { first = false; - Command::Post(0, PM_PAUSED_ERROR, 1, {}); + Command::Post(PM_PAUSED_ERROR, true); } /* Break so we warn only once for each train. */ break; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index d5d39b6e8d..3bbca46f0e 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -311,7 +311,7 @@ void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRF SetDParamStr(0, grfconfig->GetName()); SetDParam(1, engine); ShowErrorMessage(part1, part2, WL_CRITICAL); - if (!_networking) Command::Do(DC_EXEC, 0, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, 1, {}); + if (!_networking) Command::Do(DC_EXEC, critical ? PM_PAUSED_ERROR : PM_PAUSED_NORMAL, true); } /* debug output */ From d85348b1d1b9aa7099255eda7c1058f9749d1003 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 28 Nov 2021 17:37:04 +0100 Subject: [PATCH 34/60] Codechange: Template the command callback function type to allow unpacked arguments. --- src/command_func.h | 58 ++++++++---- src/network/network_client.cpp | 2 +- src/network/network_command.cpp | 156 ++++++++++++++++++++++---------- src/network/network_gui.cpp | 2 +- src/network/network_server.cpp | 2 +- src/order_backup.cpp | 2 +- src/settings.cpp | 2 +- 7 files changed, 153 insertions(+), 71 deletions(-) diff --git a/src/command_func.h b/src/command_func.h index 2a1c3dc37b..1793812a22 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -78,6 +78,20 @@ private: static int _counter; }; +#if defined(__GNUC__) && !defined(__clang__) +/* + * We cast specialized function pointers to a generic one, but don't use the + * converted value to call the function, which is safe, except that GCC + * helpfully thinks it is not. + * + * "Any pointer to function can be converted to a pointer to a different function type. + * Calling the function through a pointer to a different function type is undefined, + * but converting such pointer back to pointer to the original function type yields + * the pointer to the original function." */ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-function-type" +# define SILENCE_GCC_FUNCTION_POINTER_CAST +#endif template struct CommandHelper; @@ -148,18 +162,19 @@ public: * @param err_message Message prefix to show on error * @param args Parameters for the command */ - static inline bool Post(StringID err_message, Targs... args) { return Post(err_message, nullptr, std::forward(args)...); } + static inline bool Post(StringID err_message, Targs... args) { return Post(err_message, nullptr, std::forward(args)...); } /** * Shortcut for the long Post when not using an error message. * @param callback A callback function to call after the command is finished * @param args Parameters for the command */ - static inline bool Post(CommandCallback *callback, Targs... args) { return Post((StringID)0, callback, std::forward(args)...); } + template + static inline bool Post(Tcallback *callback, Targs... args) { return Post((StringID)0, callback, std::forward(args)...); } /** * Shortcut for the long Post when not using a callback or an error message. * @param args Parameters for the command */ - static inline bool Post(Targs... args) { return Post((StringID)0, nullptr, std::forward(args)...); } + static inline bool Post(Targs... args) { return Post((StringID)0, nullptr, std::forward(args)...); } /** * Top-level network safe command execution for the current company. @@ -171,7 +186,8 @@ public: * @param args Parameters for the command * @return \c true if the command succeeded, else \c false. */ - static bool Post(StringID err_message, CommandCallback *callback, Targs... args) + template + static bool Post(StringID err_message, Tcallback *callback, Targs... args) { return InternalPost(err_message, callback, true, false, std::forward_as_tuple(args...)); } @@ -185,7 +201,8 @@ public: * @param args Parameters for the command * @return \c true if the command succeeded, else \c false. */ - static bool PostFromNet(StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex location, std::tuple args) + template + static bool PostFromNet(StringID err_message, Tcallback *callback, bool my_cmd, TileIndex location, std::tuple args) { return InternalPost(err_message, callback, my_cmd, true, location, std::move(args)); } @@ -194,11 +211,10 @@ public: * Prepare a command to be send over the network * @param cmd The command to execute (a CMD_* value) * @param err_message Message prefix to show on error - * @param callback A callback function to call after the command is finished * @param company The company that wants to send the command * @param args Parameters for the command */ - static void SendNet(StringID err_message, CommandCallback *callback, CompanyID company, Targs... args) + static void SendNet(StringID err_message, CompanyID company, Targs... args) { auto args_tuple = std::forward_as_tuple(args...); @@ -207,7 +223,7 @@ public: tile = std::get<0>(args_tuple); } - ::NetworkSendCommand(Tcmd, err_message, callback, _current_company, tile, EndianBufferWriter::FromValue(args_tuple)); + ::NetworkSendCommand(Tcmd, err_message, nullptr, _current_company, tile, EndianBufferWriter::FromValue(args_tuple)); } /** @@ -220,9 +236,10 @@ public: * @param args Parameters for the command * @return the command cost of this function. */ - static CommandCost Unsafe(StringID err_message, CommandCallback *callback, bool my_cmd, bool estimate_only, TileIndex location, std::tuple args) + template + static CommandCost Unsafe(StringID err_message, Tcallback *callback, bool my_cmd, bool estimate_only, TileIndex location, std::tuple args) { - return Execute(err_message, callback, my_cmd, estimate_only, false, location, std::move(args)); + return Execute(err_message, reinterpret_cast(callback), my_cmd, estimate_only, false, location, std::move(args)); } protected: @@ -242,7 +259,8 @@ protected: ((SetClientIdHelper(std::get(values))), ...); } - static bool InternalPost(StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, std::tuple args) + template + static bool InternalPost(StringID err_message, Tcallback *callback, bool my_cmd, bool network_command, std::tuple args) { /* Where to show the message? */ TileIndex tile{}; @@ -253,7 +271,8 @@ protected: return InternalPost(err_message, callback, my_cmd, network_command, tile, std::move(args)); } - static bool InternalPost(StringID err_message, CommandCallback *callback, bool my_cmd, bool network_command, TileIndex tile, std::tuple args) + template + static bool InternalPost(StringID err_message, Tcallback *callback, bool my_cmd, bool network_command, TileIndex tile, std::tuple args) { auto [err, estimate_only, only_sending] = InternalPostBefore(Tcmd, GetCommandFlags(), tile, err_message, network_command); if (err) return false; @@ -261,7 +280,7 @@ protected: /* Only set client IDs when the command does not come from the network. */ if (!network_command && GetCommandFlags() & CMD_CLIENT_ID) SetClientIds(args, std::index_sequence_for{}); - CommandCost res = Execute(err_message, callback, my_cmd, estimate_only, network_command, tile, args); + CommandCost res = Execute(err_message, reinterpret_cast(callback), my_cmd, estimate_only, network_command, tile, args); InternalPostResult(res, tile, estimate_only, only_sending, err_message, my_cmd); if (!estimate_only && !only_sending && callback != nullptr) { @@ -360,20 +379,21 @@ struct CommandHelper : Com * @param location Tile location for user feedback. * @param args Parameters for the command */ - static inline bool Post(StringID err_message, TileIndex location, Targs... args) { return Post(err_message, nullptr, location, std::forward(args)...); } + static inline bool Post(StringID err_message, TileIndex location, Targs... args) { return Post(err_message, nullptr, location, std::forward(args)...); } /** * Shortcut for Post when not using a callback. * @param callback A callback function to call after the command is finished * @param location Tile location for user feedback. * @param args Parameters for the command */ - static inline bool Post(CommandCallback *callback, TileIndex location, Targs... args) { return Post((StringID)0, callback, location, std::forward(args)...); } + template + static inline bool Post(Tcallback *callback, TileIndex location, Targs... args) { return Post((StringID)0, callback, location, std::forward(args)...); } /** * Shortcut for Post when not using a callback or an error message. * @param location Tile location for user feedback. * @param args Parameters for the command* */ - static inline bool Post(TileIndex location, Targs... args) { return Post((StringID)0, nullptr, location, std::forward(args)...); } + static inline bool Post(TileIndex location, Targs... args) { return Post((StringID)0, nullptr, location, std::forward(args)...); } /** * Post variant that takes a TileIndex (for error window location and text effects) for @@ -384,12 +404,16 @@ struct CommandHelper : Com * @param args Parameters for the command * @return \c true if the command succeeded, else \c false. */ - static inline bool Post(StringID err_message, CommandCallback *callback, TileIndex location, Targs... args) + template + static inline bool Post(StringID err_message, Tcallback *callback, TileIndex location, Targs... args) { return CommandHelper::InternalPost(err_message, callback, true, false, location, std::forward_as_tuple(args...)); } }; +#ifdef SILENCE_GCC_FUNCTION_POINTER_CAST +# pragma GCC diagnostic pop +#endif template using Command = CommandHelper::ProcType, std::is_same_v::Args>>>; diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 1868f5e603..fea018a1c9 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -840,7 +840,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet * the server will give us a client-id and let us in */ _network_join_status = NETWORK_JOIN_STATUS_REGISTERING; ShowJoinStatusWindow(); - Command::SendNet(STR_NULL, nullptr, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID); + Command::SendNet(STR_NULL, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID); } } else { /* take control over an existing company */ diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 58de73b198..28300310bd 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -53,55 +53,95 @@ #include "../safeguards.h" -/** Table with all the callbacks we'll use for conversion*/ -static CommandCallback * const _callback_table[] = { - /* 0x00 */ nullptr, - /* 0x01 */ CcBuildPrimaryVehicle, - /* 0x02 */ CcBuildAirport, - /* 0x03 */ CcBuildBridge, - /* 0x04 */ CcPlaySound_CONSTRUCTION_WATER, - /* 0x05 */ CcBuildDocks, - /* 0x06 */ CcFoundTown, - /* 0x07 */ CcBuildRoadTunnel, - /* 0x08 */ CcBuildRailTunnel, - /* 0x09 */ CcBuildWagon, - /* 0x0A */ CcRoadDepot, - /* 0x0B */ CcRailDepot, - /* 0x0C */ CcPlaceSign, - /* 0x0D */ CcPlaySound_EXPLOSION, - /* 0x0E */ CcPlaySound_CONSTRUCTION_OTHER, - /* 0x0F */ CcPlaySound_CONSTRUCTION_RAIL, - /* 0x10 */ CcStation, - /* 0x11 */ CcTerraform, - /* 0x12 */ CcAI, - /* 0x13 */ CcCloneVehicle, - /* 0x14 */ nullptr, - /* 0x15 */ CcCreateGroup, - /* 0x16 */ CcFoundRandomTown, - /* 0x17 */ CcRoadStop, - /* 0x18 */ CcBuildIndustry, - /* 0x19 */ CcStartStopVehicle, - /* 0x1A */ CcGame, - /* 0x1B */ CcAddVehicleNewGroup, -}; +/** Typed list of all possible callbacks. */ +static constexpr auto _callback_tuple = std::make_tuple( + (CommandCallback *)nullptr, // Make sure this is actually a pointer-to-function. + &CcBuildPrimaryVehicle, + &CcBuildAirport, + &CcBuildBridge, + &CcPlaySound_CONSTRUCTION_WATER, + &CcBuildDocks, + &CcFoundTown, + &CcBuildRoadTunnel, + &CcBuildRailTunnel, + &CcBuildWagon, + &CcRoadDepot, + &CcRailDepot, + &CcPlaceSign, + &CcPlaySound_EXPLOSION, + &CcPlaySound_CONSTRUCTION_OTHER, + &CcPlaySound_CONSTRUCTION_RAIL, + &CcStation, + &CcTerraform, + &CcAI, + &CcCloneVehicle, + &CcCreateGroup, + &CcFoundRandomTown, + &CcRoadStop, + &CcBuildIndustry, + &CcStartStopVehicle, + &CcGame, + &CcAddVehicleNewGroup +); + +#ifdef SILENCE_GCC_FUNCTION_POINTER_CAST +/* + * We cast specialized function pointers to a generic one, but don't use the + * converted value to call the function, which is safe, except that GCC + * helpfully thinks it is not. + * + * "Any pointer to function can be converted to a pointer to a different function type. + * Calling the function through a pointer to a different function type is undefined, + * but converting such pointer back to pointer to the original function type yields + * the pointer to the original function." */ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + +/* Helpers to generate the callback table from the callback list. */ + +inline constexpr size_t _callback_tuple_size = std::tuple_size_v; + +template +inline auto MakeCallbackTable(std::index_sequence) noexcept +{ + return std::array{{ reinterpret_cast(reinterpret_cast(std::get(_callback_tuple)))... }}; // MingW64 fails linking when casting a pointer to its own type. To work around, cast it to some other type first. +} + +/** Type-erased table of callbacks. */ +static auto _callback_table = MakeCallbackTable(std::make_index_sequence<_callback_tuple_size>{}); + /* Helpers to generate the command dispatch table from the command traits. */ template static CommandDataBuffer SanitizeCmdStrings(const CommandDataBuffer &data); -template static void UnpackNetworkCommand(const CommandPacket *cp); +template static void UnpackNetworkCommand(const CommandPacket *cp); template static void NetworkReplaceCommandClientId(CommandPacket &cp, ClientID client_id); +using UnpackNetworkCommandProc = void (*)(const CommandPacket *); +using UnpackDispatchT = std::array; struct CommandDispatch { CommandDataBuffer(*Sanitize)(const CommandDataBuffer &); void (*ReplaceClientId)(CommandPacket &, ClientID); - void (*Unpack)(const CommandPacket *); + UnpackDispatchT Unpack; }; -template -inline constexpr auto MakeDispatchTable(std::integer_sequence) noexcept +template +constexpr UnpackDispatchT MakeUnpackNetworkCommand(std::index_sequence) noexcept { - return std::array{{ { &SanitizeCmdStrings(i)>, &NetworkReplaceCommandClientId(i)>, &UnpackNetworkCommand(i)> }... }}; + return UnpackDispatchT{{ {&UnpackNetworkCommand}... }}; } -static constexpr auto _cmd_dispatch = MakeDispatchTable(std::make_integer_sequence, CMD_END>{}); + +template +inline constexpr auto MakeDispatchTable(std::integer_sequence, std::index_sequence) noexcept +{ + return std::array{{ { &SanitizeCmdStrings(i)>, &NetworkReplaceCommandClientId(i)>, MakeUnpackNetworkCommand(i)>(std::make_index_sequence<_callback_tuple_size>{}) }... }}; +} +/** Command dispatch table. */ +static constexpr auto _cmd_dispatch = MakeDispatchTable(std::make_integer_sequence, CMD_END>{}, std::make_index_sequence<_callback_tuple_size>{}); + +#ifdef SILENCE_GCC_FUNCTION_POINTER_CAST +# pragma GCC diagnostic pop +#endif /** @@ -179,6 +219,20 @@ static CommandQueue _local_wait_queue; static CommandQueue _local_execution_queue; +/** + * Find the callback index of a callback pointer. + * @param callback Address of callback to search for. + * @return Callback index or std::numeric_limits::max() if the function wasn't found in the callback list. + */ +static size_t FindCallbackIndex(CommandCallback *callback) +{ + if (auto it = std::find(std::cbegin(_callback_table), std::cend(_callback_table), callback); it != std::cend(_callback_table)) { + return static_cast(std::distance(std::cbegin(_callback_table), it)); + } + + return std::numeric_limits::max(); +} + /** * Prepare a DoCommand to be send over the network * @param cmd The command to execute (a CMD_* value) @@ -259,7 +313,9 @@ void NetworkExecuteLocalCommandQueue() /* We can execute this command */ _current_company = cp->company; - _cmd_dispatch[cp->cmd].Unpack(cp); + size_t cb_index = FindCallbackIndex(cp->callback); + assert(cb_index < _callback_tuple_size); + _cmd_dispatch[cp->cmd].Unpack[cb_index](cp); queue.Pop(); delete cp; @@ -354,7 +410,7 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c cp->data = _cmd_dispatch[cp->cmd].Sanitize(p->Recv_buffer()); byte callback = p->Recv_uint8(); - if (callback >= lengthof(_callback_table)) return "invalid callback"; + if (callback >= _callback_table.size()) return "invalid callback"; cp->callback = _callback_table[callback]; return nullptr; @@ -373,16 +429,12 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp) p->Send_uint32(cp->tile); p->Send_buffer(cp->data); - byte callback = 0; - while (callback < lengthof(_callback_table) && _callback_table[callback] != cp->callback) { - callback++; - } - - if (callback == lengthof(_callback_table)) { + size_t callback = FindCallbackIndex(cp->callback); + if (callback > UINT8_MAX) { Debug(net, 0, "Unknown callback for command; no callback sent (command: {})", cp->cmd); callback = 0; // _callback_table[0] == nullptr } - p->Send_uint8 (callback); + p->Send_uint8 ((uint8)callback); } /** Helper to process a single ClientID argument. */ @@ -455,9 +507,15 @@ CommandDataBuffer SanitizeCmdStrings(const CommandDataBuffer &data) return EndianBufferWriter::FromValue(args); } -template -void UnpackNetworkCommand(const CommandPacket *cp) +/** + * Unpack a generic command packet into its actual typed components. + * @tparam Tcmd Command type to be unpacked. + * @tparam Tcb Index into the callback list. + * @param cp Command packet to unpack. + */ +template +void UnpackNetworkCommand(const CommandPacket* cp) { auto args = EndianBufferReader::ToValue::Args>(cp->data); - Command::PostFromNet(cp->err_msg, cp->callback, cp->my_cmd, cp->tile, args); + Command::PostFromNet(cp->err_msg, std::get(_callback_tuple), cp->my_cmd, cp->tile, args); } diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 0c7e361dd4..007dddb6d0 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1538,7 +1538,7 @@ private: if (_network_server) { Command::Post(CCA_NEW, INVALID_COMPANY, CRR_NONE, _network_own_client_id); } else { - Command::SendNet(STR_NULL, nullptr, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID); + Command::SendNet(STR_NULL, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID); } } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 36ab3840a4..d3cbdf9e3a 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -2081,7 +2081,7 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci) /* ci is nullptr when replaying, or for AIs. In neither case there is a client. */ ci->client_playas = c->index; NetworkUpdateClientInfo(ci->client_id); - Command::SendNet(STR_NULL, nullptr, c->index, ci->client_name); + Command::SendNet(STR_NULL, c->index, ci->client_name); } /* Announce new company on network. */ diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 46a55991da..5e634d6958 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -198,7 +198,7 @@ CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID us /* We need to circumvent the "prevention" from this command being executed * while the game is paused, so use the internal method. Nor do we want * this command to get its cost estimated when shift is pressed. */ - Command::Unsafe(STR_NULL, nullptr, true, false, ob->tile, CommandTraits::Args{ ob->tile, static_cast(user) }); + Command::Unsafe(STR_NULL, nullptr, true, false, ob->tile, CommandTraits::Args{ ob->tile, static_cast(user) }); } else { /* The command came from the game logic, i.e. the clearing of a tile. * In that case we have no need to actually sync this, just do it. */ diff --git a/src/settings.cpp b/src/settings.cpp index 25eeb964a5..f619760284 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1600,7 +1600,7 @@ void SyncCompanySettings() const SettingDesc *sd = GetSettingDesc(desc); uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object); uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object); - if (old_value != new_value) Command::SendNet(STR_NULL, nullptr, _local_company, sd->GetName(), new_value); + if (old_value != new_value) Command::SendNet(STR_NULL, _local_company, sd->GetName(), new_value); } } From 850385465543a9bd589084ec2ac6b0693c481fea Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 28 Nov 2021 22:43:38 +0100 Subject: [PATCH 35/60] Codechange: Pass unpacked command arguments to command callbacks (except Script). --- src/ai/ai_instance.cpp | 2 +- src/ai/ai_instance.hpp | 2 +- src/airport_gui.cpp | 2 +- src/bridge_gui.cpp | 7 +++---- src/command_func.h | 11 ++++++++++- src/command_type.h | 16 +++++++++++++++- src/depot_gui.cpp | 4 ++-- src/dock_gui.cpp | 4 ++-- src/game/game_instance.cpp | 2 +- src/game/game_instance.hpp | 2 +- src/group_cmd.h | 4 ++-- src/group_gui.cpp | 15 +++++---------- src/industry_cmd.h | 2 +- src/industry_gui.cpp | 5 ++--- src/main_gui.cpp | 2 +- src/network/network_command.cpp | 16 +++++++++++++++- src/rail_cmd.h | 2 +- src/rail_gui.cpp | 10 ++++------ src/road_cmd.h | 4 ++-- src/road_gui.cpp | 19 +++++++++---------- src/script/api/script_object.cpp | 2 +- src/script/api/script_object.hpp | 2 +- src/script/script_cmd.h | 4 ++-- src/script/script_instance.hpp | 2 +- src/signs_cmd.cpp | 7 ++----- src/terraform_gui.cpp | 2 +- src/town_gui.cpp | 4 ++-- src/train_gui.cpp | 2 +- src/tunnelbridge_cmd.h | 2 +- src/vehicle_cmd.h | 2 +- src/vehicle_gui.cpp | 11 ++++------- 31 files changed, 96 insertions(+), 75 deletions(-) diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index 576a81637f..e137745f19 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -113,7 +113,7 @@ void CcAI(Commands cmd, const CommandCost &result, TileIndex tile, const Command } } -CommandCallback *AIInstance::GetDoCommandCallback() +CommandCallbackData *AIInstance::GetDoCommandCallback() { return &CcAI; } diff --git a/src/ai/ai_instance.hpp b/src/ai/ai_instance.hpp index f8d2100b1c..2cdabd9913 100644 --- a/src/ai/ai_instance.hpp +++ b/src/ai/ai_instance.hpp @@ -29,7 +29,7 @@ public: private: void RegisterAPI() override; void Died() override; - CommandCallback *GetDoCommandCallback() override; + CommandCallbackData *GetDoCommandCallback() override; void LoadDummyScript() override; }; diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 5efbb98a30..6700cd3bd0 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -43,7 +43,7 @@ static void ShowBuildAirportPicker(Window *parent); SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout); -void CcBuildAirport(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcBuildAirport(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Failed()) return; diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 77261932b3..99628e75c4 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -53,15 +53,14 @@ typedef GUIList GUIBridgeList; ///< List of bridges, used in #B * @param result Whether the build succeeded * @param cmd unused * @param end_tile End tile of the bridge. - * @param data Additional bitstuffed command data. + * @param tile_start start tile + * @param transport_type transport type. */ -void CcBuildBridge(Commands cmd, const CommandCost &result, TileIndex end_tile, const CommandDataBuffer &data) +void CcBuildBridge(Commands cmd, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, byte) { if (result.Failed()) return; if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile); - auto [tile, tile_start, transport_type, bridge_type, road_rail_type] = EndianBufferReader::ToValue::Args>(data); - if (transport_type == TRANSPORT_ROAD) { DiagDirection end_direction = ReverseDiagDir(GetTunnelBridgeDirection(end_tile)); ConnectRoadToStructure(end_tile, end_direction); diff --git a/src/command_func.h b/src/command_func.h index 1793812a22..9219fd2b5f 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -284,7 +284,16 @@ protected: InternalPostResult(res, tile, estimate_only, only_sending, err_message, my_cmd); if (!estimate_only && !only_sending && callback != nullptr) { - callback(Tcmd, res, tile, EndianBufferWriter::FromValue(args)); + if constexpr (std::is_same_v) { + /* Callback that doesn't need any command arguments. */ + callback(Tcmd, res, tile); + } else if constexpr (std::is_same_v) { + /* Generic callback that takes packed arguments as a buffer. */ + callback(Tcmd, res, tile, EndianBufferWriter::FromValue(args)); + } else { + /* Callback with arguments. We assume that the tile is only interesting if it actually is in the command arguments. */ + std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd, res), args)); + } } return res.Succeeded(); diff --git a/src/command_type.h b/src/command_type.h index 0424782a23..f607969ccd 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -428,6 +428,20 @@ template struct CommandTraits; /** Storage buffer for serialized command data. */ typedef std::vector CommandDataBuffer; +/** + * Define a callback function for the client, after the command is finished. + * + * Functions of this type are called after the command is finished. The parameters + * are from the #CommandProc callback type. The boolean parameter indicates if the + * command succeeded or failed. + * + * @param cmd The command that was executed + * @param result The result of the executed command + * @param tile The tile of the command action + * @see CommandProc + */ +typedef void CommandCallback(Commands cmd, const CommandCost &result, TileIndex tile); + /** * Define a callback function for the client, after the command is finished. * @@ -441,6 +455,6 @@ typedef std::vector CommandDataBuffer; * @param data Additional data of the command * @see CommandProc */ -typedef void CommandCallback(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data); +typedef void CommandCallbackData(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data); #endif /* COMMAND_TYPE_H */ diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 7fd2e03471..c636065824 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -114,11 +114,11 @@ extern void DepotSortList(VehicleList *list); /** * This is the Callback method after the cloning attempt of a vehicle - * @param result the result of the cloning command * @param cmd unused + * @param result the result of the cloning command * @param tile unused */ -void CcCloneVehicle(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcCloneVehicle(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Failed()) return; diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index d8cd7c5d46..2ec10fe8ce 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -43,7 +43,7 @@ static void ShowBuildDocksDepotPicker(Window *parent); static Axis _ship_depot_direction; -void CcBuildDocks(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcBuildDocks(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Failed()) return; @@ -51,7 +51,7 @@ void CcBuildDocks(Commands cmd, const CommandCost &result, TileIndex tile, const if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } -void CcPlaySound_CONSTRUCTION_WATER(Commands cmd, const CommandCost &result,TileIndex tile, const CommandDataBuffer &) +void CcPlaySound_CONSTRUCTION_WATER(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_02_CONSTRUCTION_WATER, tile); } diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp index 8433567c7c..fa44ee97c1 100644 --- a/src/game/game_instance.cpp +++ b/src/game/game_instance.cpp @@ -93,7 +93,7 @@ void CcGame(Commands cmd, const CommandCost &result, TileIndex tile, const Comma } } -CommandCallback *GameInstance::GetDoCommandCallback() +CommandCallbackData *GameInstance::GetDoCommandCallback() { return &CcGame; } diff --git a/src/game/game_instance.hpp b/src/game/game_instance.hpp index 7b3b12b379..84cb20ac5a 100644 --- a/src/game/game_instance.hpp +++ b/src/game/game_instance.hpp @@ -29,7 +29,7 @@ public: private: void RegisterAPI() override; void Died() override; - CommandCallback *GetDoCommandCallback() override; + CommandCallbackData *GetDoCommandCallback() override; void LoadDummyScript() override {} }; diff --git a/src/group_cmd.h b/src/group_cmd.h index 70610de756..d3c25fda19 100644 --- a/src/group_cmd.h +++ b/src/group_cmd.h @@ -41,7 +41,7 @@ DEF_CMD_TRAIT(CMD_REMOVE_ALL_VEHICLES_GROUP, CmdRemoveAllVehiclesGroup, 0, CMDT_ DEF_CMD_TRAIT(CMD_SET_GROUP_FLAG, CmdSetGroupFlag, 0, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_SET_GROUP_LIVERY, CmdSetGroupLivery, 0, CMDT_ROUTE_MANAGEMENT) -CommandCallback CcCreateGroup; -CommandCallback CcAddVehicleNewGroup; +void CcCreateGroup(Commands cmd, const CommandCost &result, VehicleType vt, GroupID parent_group); +void CcAddVehicleNewGroup(Commands cmd, const CommandCost &result, GroupID, VehicleID veh_id, bool); #endif /* GROUP_CMD_H */ diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 3175909f0f..f614551f7c 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -1153,17 +1153,15 @@ static void CcCreateGroup(VehicleType veh_type) * Opens a 'Rename group' window for newly created group. * @param cmd Unused. * @param result Did command succeed? - * @param tile Unused. - * @param data Command data. + * @param vt Vehicle type. + * @param parent_group Parent group of the enw group. * @see CmdCreateGroup */ -void CcCreateGroup(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) +void CcCreateGroup(Commands cmd, const CommandCost &result, VehicleType vt, GroupID parent_group) { if (result.Failed()) return; - auto [vt, parent_group] = EndianBufferReader::ToValue::Args>(data); assert(vt <= VEH_AIRCRAFT); - CcCreateGroup(vt); } @@ -1171,16 +1169,13 @@ void CcCreateGroup(Commands cmd, const CommandCost &result, TileIndex tile, cons * Open rename window after adding a vehicle to a new group via drag and drop. * @param cmd Unused. * @param result Did command succeed? - * @param tile Unused. - * @param data Command data. + * @param veh_id vehicle to add to a group */ -void CcAddVehicleNewGroup(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) +void CcAddVehicleNewGroup(Commands cmd, const CommandCost &result, GroupID, VehicleID veh_id, bool) { if (result.Failed()) return; - auto [group_id, veh_id, shared] = EndianBufferReader::ToValue::Args>(data); assert(Vehicle::IsValidID(veh_id)); - CcCreateGroup(Vehicle::Get(veh_id)->type); } diff --git a/src/industry_cmd.h b/src/industry_cmd.h index b4d965f649..21d9200a30 100644 --- a/src/industry_cmd.h +++ b/src/industry_cmd.h @@ -23,6 +23,6 @@ CommandCost CmdIndustryCtrl(DoCommandFlag flags, IndustryID ind_id, IndustryActi DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_INDUSTRY_CTRL, CmdIndustryCtrl, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) -CommandCallback CcBuildIndustry; +void CcBuildIndustry(Commands cmd, const CommandCost &result, TileIndex tile, IndustryType indtype, uint32, bool, uint32); #endif /* INDUSTRY_CMD_H */ diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 8bd4dc5741..cb0e89dbda 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -222,13 +222,12 @@ void SortIndustryTypes() * @param cmd Unused. * @param result Result of the command. * @param tile Tile where the industry is placed. - * @param data Additional data of the #CMD_BUILD_INDUSTRY command. + * @param indtype Industry type. */ -void CcBuildIndustry(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) +void CcBuildIndustry(Commands cmd, const CommandCost &result, TileIndex tile, IndustryType indtype, uint32, bool, uint32) { if (result.Succeeded()) return; - auto [tile_, indtype, first_layout, fund, seed] = EndianBufferReader::ToValue::Args>(data); if (indtype < NUM_INDUSTRYTYPES) { const IndustrySpec *indsp = GetIndustrySpec(indtype); if (indsp->enabled) { diff --git a/src/main_gui.cpp b/src/main_gui.cpp index c25186164a..b2c4bfee48 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -77,7 +77,7 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl } -void CcPlaySound_EXPLOSION(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcPlaySound_EXPLOSION(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_12_EXPLOSION, tile); } diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index 28300310bd..7b3721457c 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -507,6 +507,13 @@ CommandDataBuffer SanitizeCmdStrings(const CommandDataBuffer &data) return EndianBufferWriter::FromValue(args); } + +template struct CallbackArgsHelper; +template +struct CallbackArgsHelper { + using Args = std::tuple...>; +}; + /** * Unpack a generic command packet into its actual typed components. * @tparam Tcmd Command type to be unpacked. @@ -517,5 +524,12 @@ template void UnpackNetworkCommand(const CommandPacket* cp) { auto args = EndianBufferReader::ToValue::Args>(cp->data); - Command::PostFromNet(cp->err_msg, std::get(_callback_tuple), cp->my_cmd, cp->tile, args); + + /* Check if the callback matches with the command arguments. If not, drop the callback. */ + using Tcallback = std::tuple_element_t; + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v::Args, typename CallbackArgsHelper::Args>) { + Command::PostFromNet(cp->err_msg, std::get(_callback_tuple), cp->my_cmd, cp->tile, args); + } else { + Command::PostFromNet(cp->err_msg, (CommandCallback *)nullptr, cp->my_cmd, cp->tile, args); + } } diff --git a/src/rail_cmd.h b/src/rail_cmd.h index 2299435c20..2a1b696906 100644 --- a/src/rail_cmd.h +++ b/src/rail_cmd.h @@ -38,8 +38,8 @@ DEF_CMD_TRAIT(CMD_BUILD_SIGNAL_TRACK, CmdBuildSignalTrack, CMD_AUTO, DEF_CMD_TRAIT(CMD_REMOVE_SIGNAL_TRACK, CmdRemoveSignalTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) CommandCallback CcPlaySound_CONSTRUCTION_RAIL; -CommandCallback CcRailDepot; CommandCallback CcStation; CommandCallback CcBuildRailTunnel; +void CcRailDepot(Commands cmd, const CommandCost &result, TileIndex tile, RailType rt, DiagDirection dir); #endif /* RAIL_CMD_H */ diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index bac59d7474..bab6b4c555 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -89,7 +89,7 @@ static bool IsStationAvailable(const StationSpec *statspec) return Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res); } -void CcPlaySound_CONSTRUCTION_RAIL(Commands cmd, const CommandCost &result,TileIndex tile, const CommandDataBuffer &) +void CcPlaySound_CONSTRUCTION_RAIL(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); } @@ -135,12 +135,10 @@ static const DiagDirection _place_depot_extra_dir[12] = { DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_NW, DIAGDIR_NE, }; -void CcRailDepot(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) +void CcRailDepot(Commands cmd, const CommandCost &result, TileIndex tile, RailType rt, DiagDirection dir) { if (result.Failed()) return; - auto [tile_, rt, dir] = EndianBufferReader::ToValue::Args>(data); - if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); @@ -176,7 +174,7 @@ static void PlaceRail_Waypoint(TileIndex tile) } } -void CcStation(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcStation(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Failed()) return; @@ -275,7 +273,7 @@ static void PlaceRail_Bridge(TileIndex tile, Window *w) } /** Command callback for building a tunnel */ -void CcBuildRailTunnel(Commands cmd, const CommandCost &result,TileIndex tile, const CommandDataBuffer &) +void CcBuildRailTunnel(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_CONSTRUCTION_RAIL, tile); diff --git a/src/road_cmd.h b/src/road_cmd.h index 3c142bdfed..35903dd7a3 100644 --- a/src/road_cmd.h +++ b/src/road_cmd.h @@ -31,7 +31,7 @@ DEF_CMD_TRAIT(CMD_CONVERT_ROAD, CmdConvertRoad, 0, CommandCallback CcPlaySound_CONSTRUCTION_OTHER; CommandCallback CcBuildRoadTunnel; -CommandCallback CcRoadDepot; -CommandCallback CcRoadStop; +void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, RoadType rt, DiagDirection dir); +void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 width, uint8 length, RoadStopType, bool is_drive_through, DiagDirection dir, RoadType, StationID, bool); #endif /* ROAD_CMD_H */ diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 1aa0b59ac4..275f039ba8 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -57,7 +57,7 @@ static RoadType _cur_roadtype; static DiagDirection _road_depot_orientation; static DiagDirection _road_station_picker_orientation; -void CcPlaySound_CONSTRUCTION_OTHER(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcPlaySound_CONSTRUCTION_OTHER(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); } @@ -84,7 +84,7 @@ static void PlaceRoad_Bridge(TileIndex tile, Window *w) * @param result Whether the build succeeded. * @param start_tile Starting tile of the tunnel. */ -void CcBuildRoadTunnel(Commands cmd, const CommandCost &result, TileIndex start_tile, const CommandDataBuffer &) +void CcBuildRoadTunnel(Commands cmd, const CommandCost &result, TileIndex start_tile) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, start_tile); @@ -117,12 +117,10 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) } } -void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) +void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, RoadType rt, DiagDirection dir) { if (result.Failed()) return; - auto [tile_, rt, dir] = EndianBufferReader::ToValue::Args>(data); - if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); ConnectRoadToStructure(tile, dir); @@ -130,18 +128,19 @@ void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, const /** * Command callback for building road stops. - * @param result Result of the build road stop command. * @param cmd Unused. + * @param result Result of the build road stop command. * @param tile Start tile. - * @param data Command data. + * @param width Width of the road stop. + * @param length Length of the road stop. + * @param is_drive_through False for normal stops, true for drive-through. + * @param dir Entrance direction (#DiagDirection) for normal stops. Converted to the axis for drive-through stops. * @see CmdBuildRoadStop */ -void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) +void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 width, uint8 length, RoadStopType, bool is_drive_through, DiagDirection dir, RoadType, StationID, bool) { if (result.Failed()) return; - auto [tile_, width, length, stop_type, is_drive_through, dir, rt, station_to_join, adjacent] = EndianBufferReader::ToValue::Args>(data); - if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); TileArea roadstop_area(tile, width, length); diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index de4fab481b..ff109dbdfc 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -296,7 +296,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() return GetStorage()->callback_value[index]; } -/* static */ CommandCallback *ScriptObject::GetDoCommandCallback() +/* static */ CommandCallbackData *ScriptObject::GetDoCommandCallback() { return ScriptObject::GetActiveInstance()->GetDoCommandCallback(); } diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index 8d9be14c46..11d9542c89 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -326,7 +326,7 @@ private: /* Helper functions for DoCommand. */ static std::tuple DoCommandPrep(); static bool DoCommandProcessResult(const CommandCost &res, Script_SuspendCallbackProc *callback, bool estimate_only); - static CommandCallback *GetDoCommandCallback(); + static CommandCallbackData *GetDoCommandCallback(); }; namespace ScriptObjectInternal { diff --git a/src/script/script_cmd.h b/src/script/script_cmd.h index bf6aa50c72..c1b3a9b23c 100644 --- a/src/script/script_cmd.h +++ b/src/script/script_cmd.h @@ -12,7 +12,7 @@ #include "../command_type.h" -CommandCallback CcAI; -CommandCallback CcGame; +CommandCallbackData CcAI; +CommandCallbackData CcGame; #endif /* SCRIPT_CMD_H */ diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp index c30fd14996..290568fddf 100644 --- a/src/script/script_instance.hpp +++ b/src/script/script_instance.hpp @@ -235,7 +235,7 @@ protected: /** * Get the callback handling DoCommands in case of networking. */ - virtual CommandCallback *GetDoCommandCallback() = 0; + virtual CommandCallbackData *GetDoCommandCallback() = 0; /** * Load the dummy script. diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index 8d20137b4a..f50e375837 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.cpp @@ -105,14 +105,11 @@ CommandCost CmdRenameSign(DoCommandFlag flags, SignID sign_id, const std::string /** * Callback function that is called after a sign is placed - * @param result of the operation * @param cmd unused + * @param result of the operation * @param tile unused - * @param p1 unused - * @param p2 unused - * @param text unused */ -void CcPlaceSign(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcPlaceSign(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Failed()) return; diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 2e3fec0956..ecdc8a6dd4 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -44,7 +44,7 @@ #include "safeguards.h" -void CcTerraform(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcTerraform(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 90aa588552..0c5f86ab7c 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -1009,7 +1009,7 @@ void ShowTownDirectory() new TownDirectoryWindow(&_town_directory_desc); } -void CcFoundTown(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcFoundTown(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Failed()) return; @@ -1017,7 +1017,7 @@ void CcFoundTown(Commands cmd, const CommandCost &result, TileIndex tile, const if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } -void CcFoundRandomTown(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcFoundRandomTown(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Succeeded()) ScrollMainWindowToTile(Town::Get(_new_town_id)->xy); } diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 268b5b40b8..d6c7320e65 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -26,7 +26,7 @@ * @param result The result of the command. * @param tile The tile the command was executed on. */ -void CcBuildWagon(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &) +void CcBuildWagon(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Failed()) return; diff --git a/src/tunnelbridge_cmd.h b/src/tunnelbridge_cmd.h index ae924cf69d..d49131263d 100644 --- a/src/tunnelbridge_cmd.h +++ b/src/tunnelbridge_cmd.h @@ -20,6 +20,6 @@ CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportT DEF_CMD_TRAIT(CMD_BUILD_BRIDGE, CmdBuildBridge, CMD_DEITY | CMD_AUTO | CMD_NO_WATER, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_BUILD_TUNNEL, CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) -CommandCallback CcBuildBridge; +void CcBuildBridge(Commands cmd, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, byte); #endif /* TUNNELBRIDGE_CMD_H */ diff --git a/src/vehicle_cmd.h b/src/vehicle_cmd.h index b2ad082286..38852347c8 100644 --- a/src/vehicle_cmd.h +++ b/src/vehicle_cmd.h @@ -40,7 +40,7 @@ DEF_CMD_TRAIT(CMD_DEPOT_SELL_ALL_VEHICLES, CmdDepotSellAllVehicles, 0, DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION) CommandCallback CcBuildPrimaryVehicle; -CommandCallback CcStartStopVehicle; +void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id, bool); template inline EndianBufferWriter &operator <<(EndianBufferWriter &buffer, const VehicleListIdentifier &vli) diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 289a821e56..4965cac0a9 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2617,16 +2617,14 @@ static const StringID _vehicle_msg_translation_table[][4] = { /** * This is the Callback method after attempting to start/stop a vehicle - * @param result the result of the start/stop command * @param cmd unused - * @param tile unused - * @param data Command data + * @param result the result of the start/stop command + * @param veh_id Vehicle ID. */ -void CcStartStopVehicle(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) +void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id, bool) { if (result.Failed()) return; - VehicleID veh_id = std::get<0>(EndianBufferReader::ToValue::Args>(data)); const Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle() || v->owner != _local_company) return; @@ -3124,9 +3122,8 @@ void StopGlobalFollowVehicle(const Vehicle *v) * @param result indicates completion (or not) of the operation * @param cmd unused * @param tile unused - * @param data unused */ -void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) +void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, TileIndex tile) { if (result.Failed()) return; From 3e85e833a707e6b781d00eae09c9465bacbf1d69 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Tue, 30 Nov 2021 00:52:23 +0100 Subject: [PATCH 36/60] Codechange: Add support for additional command result values. --- src/ai/ai_instance.cpp | 6 +- src/command_func.h | 97 +++++++++++++++++++++++--------- src/command_type.h | 13 ++++- src/game/game_instance.cpp | 6 +- src/network/network_command.cpp | 2 +- src/script/api/script_object.cpp | 10 ++++ src/script/api/script_object.hpp | 36 ++++++++++-- src/script/script_instance.cpp | 3 +- src/script/script_instance.hpp | 3 +- src/script/script_storage.hpp | 1 + 10 files changed, 136 insertions(+), 41 deletions(-) diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index e137745f19..0e8355d733 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -18,6 +18,7 @@ #include "ai.hpp" #include "../script/script_storage.hpp" +#include "../script/script_cmd.h" #include "ai_info.hpp" #include "ai_instance.hpp" @@ -96,8 +97,9 @@ ScriptInfo *AIInstance::FindLibrary(const char *library, int version) * @param result The result of the command. * @param tile The tile on which the command was executed. * @param data Command data as given to Command<>::Post. + * @param result_data Additional returned data from the command. */ -void CcAI(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data) +void CcAI(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data) { /* * The company might not exist anymore. Check for this. @@ -108,7 +110,7 @@ void CcAI(Commands cmd, const CommandCost &result, TileIndex tile, const Command const Company *c = Company::GetIfValid(_current_company); if (c == nullptr || c->ai_instance == nullptr) return; - if (c->ai_instance->DoCommandCallback(result, tile, data, cmd)) { + if (c->ai_instance->DoCommandCallback(result, tile, data, std::move(result_data), cmd)) { c->ai_instance->Continue(); } } diff --git a/src/command_func.h b/src/command_func.h index 9219fd2b5f..117fed9177 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -111,10 +111,30 @@ protected: * Templated wrapper that exposes the command parameter arguments * for the various Command::Do/Post calls. * @tparam Tcmd The command-id to execute. + * @tparam Tret Return type of the command. * @tparam Targs The command parameter types. */ -template -struct CommandHelper : protected CommandHelperBase { +template +struct CommandHelper : protected CommandHelperBase { +private: + /** Extract the \c CommandCost from a command proc result. */ + static inline CommandCost &ExtractCommandCost(Tret &ret) + { + if constexpr (std::is_same_v) { + return ret; + } else { + return std::get<0>(ret); + } + } + + /** Make a command proc result from a \c CommandCost. */ + static inline Tret MakeResult(const CommandCost &cost) + { + Tret ret{}; + ExtractCommandCost(ret) = cost; + return ret; + } + public: /** * This function executes a given command with the parameters from the #CommandProc parameter list. @@ -129,12 +149,12 @@ public: * @see CommandProc * @return the cost */ - static CommandCost Do(DoCommandFlag flags, Targs... args) + static Tret Do(DoCommandFlag flags, Targs... args) { if constexpr (std::is_same_v>>) { /* Do not even think about executing out-of-bounds tile-commands. */ TileIndex tile = std::get<0>(std::make_tuple(args...)); - if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return CMD_ERROR; + if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return MakeResult(CMD_ERROR); } RecursiveCommandCounter counter{}; @@ -142,17 +162,17 @@ public: /* Only execute the test call if it's toplevel, or we're not execing. */ if (counter.IsTopLevel() || !(flags & DC_EXEC)) { InternalDoBefore(counter.IsTopLevel(), true); - CommandCost res = CommandTraits::proc(flags & ~DC_EXEC, args...); - InternalDoAfter(res, flags, counter.IsTopLevel(), true); // Can modify res. + Tret res = CommandTraits::proc(flags & ~DC_EXEC, args...); + InternalDoAfter(ExtractCommandCost(res), flags, counter.IsTopLevel(), true); // Can modify res. - if (res.Failed() || !(flags & DC_EXEC)) return res; + if (ExtractCommandCost(res).Failed() || !(flags & DC_EXEC)) return res; } /* Execute the command here. All cost-relevant functions set the expenses type * themselves to the cost object at some point. */ InternalDoBefore(counter.IsTopLevel(), false); - CommandCost res = CommandTraits::proc(flags, args...); - InternalDoAfter(res, flags, counter.IsTopLevel(), false); + Tret res = CommandTraits::proc(flags, args...); + InternalDoAfter(ExtractCommandCost(res), flags, counter.IsTopLevel(), false); return res; } @@ -237,7 +257,7 @@ public: * @return the command cost of this function. */ template - static CommandCost Unsafe(StringID err_message, Tcallback *callback, bool my_cmd, bool estimate_only, TileIndex location, std::tuple args) + static Tret Unsafe(StringID err_message, Tcallback *callback, bool my_cmd, bool estimate_only, TileIndex location, std::tuple args) { return Execute(err_message, reinterpret_cast(callback), my_cmd, estimate_only, false, location, std::move(args)); } @@ -259,6 +279,13 @@ protected: ((SetClientIdHelper(std::get(values))), ...); } + /** Remove the first element of a tuple. */ + template