diff --git a/src/news_func.h b/src/news_func.h index f218db3634..53765f314a 100644 --- a/src/news_func.h +++ b/src/news_func.h @@ -60,8 +60,6 @@ void InitNewsItemStructs(); extern const NewsItem *_statusbar_news_item; extern bool _news_ticker_sound; -extern NewsTypeData _news_type_data[]; - void DeleteInvalidEngineNews(); void DeleteVehicleNews(VehicleID vid, StringID news); void DeleteStationNews(StationID sid); diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 070bf0abf1..e6bf957a4b 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -32,6 +32,7 @@ #include "core/geometry_func.hpp" #include "command_func.h" #include "company_base.h" +#include "settings_internal.h" #include "widgets/news_widget.h" @@ -222,27 +223,40 @@ const WindowDesc* GetNewsWindowLayout(NewsFlag flags) /** * Per-NewsType data */ -NewsTypeData _news_type_data[] = { - /* name, age, sound, display, description */ - NewsTypeData("arrival_player", 60, SND_1D_APPLAUSE, ND_FULL, STR_NEWS_MESSAGE_TYPE_ARRIVAL_OF_FIRST_VEHICLE_OWN ), ///< NT_ARRIVAL_COMPANY - NewsTypeData("arrival_other", 60, SND_1D_APPLAUSE, ND_SUMMARY, STR_NEWS_MESSAGE_TYPE_ARRIVAL_OF_FIRST_VEHICLE_OTHER ), ///< NT_ARRIVAL_OTHER - NewsTypeData("accident", 90, SND_BEGIN, ND_FULL, STR_NEWS_MESSAGE_TYPE_ACCIDENTS_DISASTERS ), ///< NT_ACCIDENT - NewsTypeData("company_info", 60, SND_BEGIN, ND_FULL, STR_NEWS_MESSAGE_TYPE_COMPANY_INFORMATION ), ///< NT_COMPANY_INFO - NewsTypeData("open", 90, SND_BEGIN, ND_SUMMARY, STR_NEWS_MESSAGE_TYPE_INDUSTRY_OPEN ), ///< NT_INDUSTRY_OPEN - NewsTypeData("close", 90, SND_BEGIN, ND_SUMMARY, STR_NEWS_MESSAGE_TYPE_INDUSTRY_CLOSE ), ///< NT_INDUSTRY_CLOSE - NewsTypeData("economy", 30, SND_BEGIN, ND_FULL, STR_NEWS_MESSAGE_TYPE_ECONOMY_CHANGES ), ///< NT_ECONOMY - NewsTypeData("production_player", 30, SND_BEGIN, ND_SUMMARY, STR_NEWS_MESSAGE_TYPE_INDUSTRY_CHANGES_SERVED_BY_COMPANY ), ///< NT_INDUSTRY_COMPANY - NewsTypeData("production_other", 30, SND_BEGIN, ND_OFF, STR_NEWS_MESSAGE_TYPE_INDUSTRY_CHANGES_SERVED_BY_OTHER ), ///< NT_INDUSTRY_OTHER - NewsTypeData("production_nobody", 30, SND_BEGIN, ND_OFF, STR_NEWS_MESSAGE_TYPE_INDUSTRY_CHANGES_UNSERVED ), ///< NT_INDUSTRY_NOBODY - NewsTypeData("advice", 150, SND_BEGIN, ND_FULL, STR_NEWS_MESSAGE_TYPE_ADVICE_INFORMATION_ON_COMPANY ), ///< NT_ADVICE - NewsTypeData("new_vehicles", 30, SND_1E_OOOOH, ND_FULL, STR_NEWS_MESSAGE_TYPE_NEW_VEHICLES ), ///< NT_NEW_VEHICLES - NewsTypeData("acceptance", 90, SND_BEGIN, ND_FULL, STR_NEWS_MESSAGE_TYPE_CHANGES_OF_CARGO_ACCEPTANCE ), ///< NT_ACCEPTANCE - NewsTypeData("subsidies", 180, SND_BEGIN, ND_SUMMARY, STR_NEWS_MESSAGE_TYPE_SUBSIDIES ), ///< NT_SUBSIDIES - NewsTypeData("general", 60, SND_BEGIN, ND_FULL, STR_NEWS_MESSAGE_TYPE_GENERAL_INFORMATION ), ///< NT_GENERAL +static NewsTypeData _news_type_data[] = { + /* name, age, sound, */ + NewsTypeData("news_display.arrival_player", 60, SND_1D_APPLAUSE ), ///< NT_ARRIVAL_COMPANY + NewsTypeData("news_display.arrival_other", 60, SND_1D_APPLAUSE ), ///< NT_ARRIVAL_OTHER + NewsTypeData("news_display.accident", 90, SND_BEGIN ), ///< NT_ACCIDENT + NewsTypeData("news_display.company_info", 60, SND_BEGIN ), ///< NT_COMPANY_INFO + NewsTypeData("news_display.open", 90, SND_BEGIN ), ///< NT_INDUSTRY_OPEN + NewsTypeData("news_display.close", 90, SND_BEGIN ), ///< NT_INDUSTRY_CLOSE + NewsTypeData("news_display.economy", 30, SND_BEGIN ), ///< NT_ECONOMY + NewsTypeData("news_display.production_player", 30, SND_BEGIN ), ///< NT_INDUSTRY_COMPANY + NewsTypeData("news_display.production_other", 30, SND_BEGIN ), ///< NT_INDUSTRY_OTHER + NewsTypeData("news_display.production_nobody", 30, SND_BEGIN ), ///< NT_INDUSTRY_NOBODY + NewsTypeData("news_display.advice", 150, SND_BEGIN ), ///< NT_ADVICE + NewsTypeData("news_display.new_vehicles", 30, SND_1E_OOOOH ), ///< NT_NEW_VEHICLES + NewsTypeData("news_display.acceptance", 90, SND_BEGIN ), ///< NT_ACCEPTANCE + NewsTypeData("news_display.subsidies", 180, SND_BEGIN ), ///< NT_SUBSIDIES + NewsTypeData("news_display.general", 60, SND_BEGIN ), ///< NT_GENERAL }; assert_compile(lengthof(_news_type_data) == NT_END); +/** + * Return the news display option. + * @return display options + */ +NewsDisplay NewsTypeData::GetDisplay() const +{ + uint index; + const SettingDesc *sd = GetSettingFromName(this->name, &index); + assert(sd != NULL); + void *ptr = GetVariableAddress(NULL, &sd->save); + return (NewsDisplay)ReadValue(ptr, sd->save.conv); +} + /** Window class displaying a news item. */ struct NewsWindow : Window { uint16 chat_height; ///< Height of the chat window. @@ -587,7 +601,7 @@ static void MoveToNextItem() /* check the date, don't show too old items */ if (_date - _news_type_data[type].age > ni->date) return; - switch (_news_type_data[type].display) { + switch (_news_type_data[type].GetDisplay()) { default: NOT_REACHED(); case ND_OFF: // Off - show nothing only a small reminder in the status bar InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SHOW_REMINDER); @@ -907,7 +921,7 @@ void ShowLastNewsMessage() } bool wrap = false; for (;;) { - if (_news_type_data[ni->type].display != ND_OFF) { + if (_news_type_data[ni->type].GetDisplay() != ND_OFF) { ShowNewsMessage(ni); break; } diff --git a/src/news_type.h b/src/news_type.h index 40b6e2c941..fee7ae38e3 100644 --- a/src/news_type.h +++ b/src/news_type.h @@ -113,24 +113,21 @@ struct NewsTypeData { const char * const name; ///< Name const byte age; ///< Maximum age of news items (in days) const SoundFx sound; ///< Sound - NewsDisplay display; ///< Display mode (off, summary, full) - const StringID description; ///< Description of the news type in news settings window /** * Construct this entry. * @param name The name of the type. * @param age The maximum age for these messages. * @param sound The sound to play. - * @param description The description for this type of messages. */ - NewsTypeData(const char *name, byte age, SoundFx sound, NewsDisplay display, StringID description) : + NewsTypeData(const char *name, byte age, SoundFx sound) : name(name), age(age), - sound(sound), - display(display), - description(description) + sound(sound) { } + + NewsDisplay GetDisplay() const; }; /** Information about a single item of news. */ diff --git a/src/settings.cpp b/src/settings.cpp index 27a68785d1..e1649b269f 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1243,81 +1243,6 @@ static void HandleOldDiffCustom(bool savegame) } } -/** - * tries to convert newly introduced news settings based on old ones - * @param name pointer to the string defining name of the old news config - * @param value pointer to the string defining value of the old news config - * @returns true if conversion could have been made - */ -static bool ConvertOldNewsSetting(const char *name, const char *value) -{ - if (strcasecmp(name, "openclose") == 0) { - /* openclose has been split in "open" and "close". - * So the job is now to decrypt the value of the old news config - * and give it to the two newly introduced ones*/ - - NewsDisplay display = ND_OFF; // default - if (strcasecmp(value, "full") == 0) { - display = ND_FULL; - } else if (strcasecmp(value, "summarized") == 0) { - display = ND_SUMMARY; - } - /* tranfert of values */ - _news_type_data[NT_INDUSTRY_OPEN].display = display; - _news_type_data[NT_INDUSTRY_CLOSE].display = display; - return true; - } - return false; -} - -/** - * Load newstype settings from a configuration file. - * @param ini the configuration to read from. - * @param grpname Name of the group containing the news type settings. - */ -static void NewsDisplayLoadConfig(IniFile *ini, const char *grpname) -{ - IniGroup *group = ini->GetGroup(grpname); - IniItem *item; - - /* If no group exists, return */ - if (group == NULL) return; - - for (item = group->item; item != NULL; item = item->next) { - int news_item = -1; - for (int i = 0; i < NT_END; i++) { - if (strcasecmp(item->name, _news_type_data[i].name) == 0) { - news_item = i; - break; - } - } - - /* the config been read is not within current aceptable config */ - if (news_item == -1) { - /* if the conversion function cannot process it, advice by a debug warning*/ - if (!ConvertOldNewsSetting(item->name, item->value)) { - DEBUG(misc, 0, "Invalid display option: %s", item->name); - } - /* in all cases, there is nothing left to do */ - continue; - } - - if (StrEmpty(item->value)) { - DEBUG(misc, 0, "Empty display value for newstype %s", item->name); - continue; - } else if (strcasecmp(item->value, "full") == 0) { - _news_type_data[news_item].display = ND_FULL; - } else if (strcasecmp(item->value, "off") == 0) { - _news_type_data[news_item].display = ND_OFF; - } else if (strcasecmp(item->value, "summarized") == 0) { - _news_type_data[news_item].display = ND_SUMMARY; - } else { - DEBUG(misc, 0, "Invalid display value for newstype %s: %s", item->name, item->value); - continue; - } - } -} - static void AILoadConfig(IniFile *ini, const char *grpname) { IniGroup *group = ini->GetGroup(grpname); @@ -1447,25 +1372,6 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati return first; } -/** - * Write newstype settings to a configuration file. - * @param ini The configuration to write to. - * @param grpname Name of the group containing the news type settings. - */ -static void NewsDisplaySaveConfig(IniFile *ini, const char *grpname) -{ - IniGroup *group = ini->GetGroup(grpname); - - for (int i = 0; i < NT_END; i++) { - const char *value; - int v = _news_type_data[i].display; - - value = (v == ND_OFF ? "off" : (v == ND_SUMMARY ? "summarized" : "full")); - - group->GetItem(_news_type_data[i].name, true)->SetValue(value); - } -} - static void AISaveConfig(IniFile *ini, const char *grpname) { IniGroup *group = ini->GetGroup(grpname); @@ -1593,7 +1499,6 @@ void LoadFromConfig(bool minimal) if (!minimal) { _grfconfig_newgame = GRFLoadConfig(ini, "newgrf", false); _grfconfig_static = GRFLoadConfig(ini, "newgrf-static", true); - NewsDisplayLoadConfig(ini, "news_display"); AILoadConfig(ini, "ai_players"); GameLoadConfig(ini, "game_scripts"); @@ -1625,7 +1530,6 @@ void SaveToConfig() HandleSettingDescs(ini, IniSaveSettings, IniSaveSettingList); GRFSaveConfig(ini, "newgrf", _grfconfig_newgame); GRFSaveConfig(ini, "newgrf-static", _grfconfig_static); - NewsDisplaySaveConfig(ini, "news_display"); AISaveConfig(ini, "ai_players"); GameSaveConfig(ini, "game_scripts"); SaveVersionInConfig(ini); diff --git a/src/settings_type.h b/src/settings_type.h index b182191a7f..a6326c3df7 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -182,6 +182,25 @@ struct LocaleSettings { char *digit_decimal_separator; ///< decimal separator }; +/** Settings related to news */ +struct NewsSettings { + uint8 arrival_player; ///< NewsDisplay of vehicles arriving at new stations of current player + uint8 arrival_other; ///< NewsDisplay of vehicles arriving at new stations of other players + uint8 accident; ///< NewsDisplay of accidents that occur + uint8 company_info; ///< NewsDisplay of general company information + uint8 open; ///< NewsDisplay on new industry constructions + uint8 close; ///< NewsDisplay about closing industries + uint8 economy; ///< NewsDisplay on economical changes + uint8 production_player; ///< NewsDisplay of production changes of industries affecting current player + uint8 production_other; ///< NewsDisplay of production changes of industries affecting competitors + uint8 production_nobody; ///< NewsDisplay of production changes of industries affecting no one + uint8 advice; ///< NewsDisplay on advice affecting the player's vehicles + uint8 new_vehicles; ///< NewsDisplay of new vehicles becoming available + uint8 acceptance; ///< NewsDisplay on changes affecting the acceptance of cargo at stations + uint8 subsidies; ///< NewsDisplay of changes on subsidies + uint8 general; ///< NewsDisplay of other topics +}; + /** All settings related to the network. */ struct NetworkSettings { #ifdef ENABLE_NETWORK @@ -496,6 +515,7 @@ struct ClientSettings { NetworkSettings network; ///< settings related to the network CompanySettings company; ///< default values for per-company settings MusicSettings music; ///< settings related to music/sound + NewsSettings news_display; ///< news display settings. }; /** The current settings for this game. */ diff --git a/src/table/gameopt_settings.ini b/src/table/gameopt_settings.ini index 968191f128..8f7861942a 100644 --- a/src/table/gameopt_settings.ini +++ b/src/table/gameopt_settings.ini @@ -25,6 +25,7 @@ static const char *_server_langs = "ANY|ENGLISH|GERMAN|FRENCH|BRAZILIAN|BULGARIA #endif /* ENABLE_NETWORK */ static const char *_osk_activation = "disabled|double|single|immediately"; static const char *_settings_profiles = "easy|medium|hard"; +static const char *_news_display = "off|summarized|full"; static const SettingDesc _gameopt_settings[] = { /* In version 4 a new difficulty setting has been added to the difficulty settings, diff --git a/src/table/settings.ini b/src/table/settings.ini index 95c33e95d0..ec74265a12 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -2969,6 +2969,141 @@ flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = false cat = SC_BASIC +[SDTC_OMANY] +var = news_display.arrival_player +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 2 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.arrival_other +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 1 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.accident +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 2 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.company_info +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 2 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.open +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 1 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.close +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 1 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.economy +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 2 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.production_player +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 1 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.production_other +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 0 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.production_nobody +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 0 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.advice +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 2 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.new_vehicles +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 2 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.acceptance +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 2 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.subsidies +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 1 +max = 2 +full = _news_display + +[SDTC_OMANY] +var = news_display.general +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 2 +max = 2 +full = _news_display + [SDTC_VAR] ifdef = ENABLE_NETWORK var = gui.network_chat_box_width