1 /*
2 Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY.
11
12 See the COPYING file for more details.
13 */
14
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16
17 #include "game_board.hpp"
18 #include "game_display.hpp"
19 #include "preferences/game.hpp"
20 #include "gettext.hpp"
21 #include "lexical_cast.hpp"
22 #include "log.hpp"
23 #include "map/map.hpp"
24 #include "serialization/string_utils.hpp"
25 #include "serialization/unicode_cast.hpp"
26 #include "map_settings.hpp"
27 #include "units/unit.hpp"
28 #include "units/map.hpp"
29 #include "wml_exception.hpp"
30
31 #include <cassert>
32
33 static lg::log_domain log_config("config");
34 #define ERR_CFG LOG_STREAM(err , log_config)
35
36 using acquaintances_map = std::map<std::string, preferences::acquaintance>;
37
38 namespace {
39
40 bool message_private_on = false;
41
42 bool haloes = true;
43
44 std::map<std::string, std::set<std::string>> completed_campaigns;
45 std::set<std::string> encountered_units_set;
46 std::set<t_translation::terrain_code> encountered_terrains_set;
47
48 std::map<std::string, std::vector<std::string>> history_map;
49
50 acquaintances_map acquaintances;
51
52 std::vector<std::string> mp_modifications;
53 bool mp_modifications_initialized = false;
54 std::vector<std::string> sp_modifications;
55 bool sp_modifications_initialized = false;
56
57 config option_values;
58 bool options_initialized = false;
59
60 bool authenticated = false;
61
initialize_modifications(bool mp=true)62 void initialize_modifications(bool mp = true)
63 {
64 if (mp) {
65 mp_modifications = utils::split(preferences::get("mp_modifications"), ',');
66 mp_modifications_initialized = true;
67 } else {
68 sp_modifications = utils::split(preferences::get("sp_modifications"), ',');
69 sp_modifications_initialized = true;
70 }
71 }
72
73 } // anon namespace
74
75 namespace preferences {
76
77
manager()78 manager::manager() :
79 base()
80 {
81 set_music_volume(music_volume());
82 set_sound_volume(sound_volume());
83
84 set_show_haloes(preferences::get("show_haloes", true));
85 if (!preferences::get("remember_timer_settings", false)) {
86 preferences::erase("mp_countdown_init_time");
87 preferences::erase("mp_countdown_reservoir_time");
88 preferences::erase("mp_countdown_turn_bonus");
89 preferences::erase("mp_countdown_action_bonus");
90 }
91
92 // We save the password encrypted now. Erase any saved passwords in the prefs file.
93 preferences::erase("password");
94 preferences::erase("password_is_wrapped");
95
96 // TODO: remove when we re-enable font scaling configuration.
97 preferences::erase("font_scale");
98
99 /*
100 completed_campaigns = "A,B,C"
101 [completed_campaigns]
102 [campaign]
103 name = "A"
104 difficulty_levels = "EASY,MEDIUM"
105 [/campaign]
106 [/completed_campaigns]
107 */
108 for (const std::string &c : utils::split(preferences::get("completed_campaigns"))) {
109 completed_campaigns[c]; // create the elements
110 }
111 if (const config &ccc = preferences::get_child("completed_campaigns")) {
112 for (const config &cc : ccc.child_range("campaign")) {
113 std::set<std::string> &d = completed_campaigns[cc["name"]];
114 std::vector<std::string> nd = utils::split(cc["difficulty_levels"]);
115 std::copy(nd.begin(), nd.end(), std::inserter(d, d.begin()));
116 }
117 }
118
119 const std::vector<std::string> v (utils::split(preferences::get("encountered_units")));
120 encountered_units_set.insert(v.begin(), v.end());
121
122 const t_translation::ter_list terrain (t_translation::read_list(preferences::get("encountered_terrain_list")));
123 encountered_terrains_set.insert(terrain.begin(), terrain.end());
124
125 if (const config &history = preferences::get_child("history"))
126 {
127 /* Structure of the history
128 [history]
129 [history_id]
130 [line]
131 message = foobar
132 [/line]
133 */
134 for (const config::any_child &h : history.all_children_range())
135 {
136 for (const config &l : h.cfg.child_range("line")) {
137 history_map[h.key].push_back(l["message"]);
138 }
139 }
140 }
141 }
142
~manager()143 manager::~manager()
144 {
145 config campaigns;
146 typedef const std::pair<std::string, std::set<std::string>> cc_elem;
147 for (cc_elem &elem : completed_campaigns) {
148 config cmp;
149 cmp["name"] = elem.first;
150 cmp["difficulty_levels"] = utils::join(elem.second);
151 campaigns.add_child("campaign", cmp);
152 }
153 preferences::set_child("completed_campaigns", campaigns);
154 std::vector<std::string> v (encountered_units_set.begin(), encountered_units_set.end());
155 preferences::set("encountered_units", utils::join(v));
156 t_translation::ter_list terrain (encountered_terrains_set.begin(), encountered_terrains_set.end());
157 preferences::set("encountered_terrain_list", t_translation::write_list(terrain));
158
159 /* Structure of the history
160 [history]
161 [history_id]
162 [line]
163 message = foobar
164 [/line]
165 */
166 config history;
167 typedef std::pair<std::string, std::vector<std::string>> hack;
168 for (const hack& history_id : history_map) {
169
170 config history_id_cfg; // [history_id]
171 for (const std::string& line : history_id.second) {
172 config cfg; // [line]
173
174 cfg["message"] = line;
175 history_id_cfg.add_child("line", std::move(cfg));
176 }
177
178 history.add_child(history_id.first, history_id_cfg);
179 }
180 preferences::set_child("history", history);
181
182 history_map.clear();
183 encountered_units_set.clear();
184 encountered_terrains_set.clear();
185 }
186
is_authenticated()187 bool is_authenticated() {
188 return authenticated;
189 }
190
parse_admin_authentication(const std::string & sender,const std::string & message)191 void parse_admin_authentication(const std::string& sender, const std::string& message) {
192 if(sender != "server") return;
193 if(message.compare(0, 43, "You are now recognized as an administrator.") == 0) {
194 authenticated = true;
195 } else if(message.compare(0, 50, "You are no longer recognized as an administrator.") == 0) {
196 authenticated = false;
197 }
198 }
199
admin_authentication_reset()200 admin_authentication_reset::admin_authentication_reset()
201 {
202 }
203
~admin_authentication_reset()204 admin_authentication_reset::~admin_authentication_reset()
205 {
206 authenticated = false;
207 }
208
load_acquaintances()209 static void load_acquaintances() {
210 if(acquaintances.empty()) {
211 for (const config &acfg : preferences::get_prefs()->child_range("acquaintance")) {
212 acquaintance ac = acquaintance(acfg);
213 acquaintances[ac.get_nick()] = ac;
214 }
215 }
216 }
217
save_acquaintances()218 static void save_acquaintances()
219 {
220 config *cfg = preferences::get_prefs();
221 cfg->clear_children("acquaintance");
222
223 for(std::map<std::string, acquaintance>::iterator i = acquaintances.begin();
224 i != acquaintances.end(); ++i)
225 {
226 config& item = cfg->add_child("acquaintance");
227 i->second.save(item);
228 }
229 }
230
get_acquaintances()231 const std::map<std::string, acquaintance> & get_acquaintances() {
232 load_acquaintances();
233 return acquaintances;
234 }
235
236 //returns acquaintances in the form nick => notes where the status = filter
get_acquaintances_nice(const std::string & filter)237 std::map<std::string, std::string> get_acquaintances_nice(const std::string& filter) {
238 load_acquaintances();
239 std::map<std::string, std::string> ac_nice;
240
241 for(std::map<std::string, acquaintance>::iterator i = acquaintances.begin(); i != acquaintances.end(); ++i)
242 {
243 if(i->second.get_status() == filter) {
244 ac_nice[i->second.get_nick()] = i->second.get_notes();
245 }
246 }
247
248 return ac_nice;
249 }
250
add_acquaintance(const std::string & nick,const std::string & mode,const std::string & notes)251 std::pair<preferences::acquaintance*, bool> add_acquaintance(const std::string& nick, const std::string& mode, const std::string& notes)
252 {
253 if(!utils::isvalid_wildcard(nick)) {
254 return std::make_pair(nullptr, false);
255 }
256
257 preferences::acquaintance new_entry(nick, mode, notes);
258
259 acquaintances_map::iterator iter;
260 bool success;
261
262 std::tie(iter, success) = acquaintances.emplace(nick, new_entry);
263
264 if(!success) {
265 iter->second = new_entry;
266 }
267
268 save_acquaintances();
269
270 return std::make_pair(&iter->second, success);
271 }
272
remove_acquaintance(const std::string & nick)273 bool remove_acquaintance(const std::string& nick) {
274 std::map<std::string, acquaintance>::iterator i = acquaintances.find(nick);
275
276 //nick might include the notes, depending on how we're removing
277 if(i == acquaintances.end()) {
278 size_t pos = nick.find_first_of(' ');
279
280 if(pos != std::string::npos) {
281 i = acquaintances.find(nick.substr(0, pos));
282 }
283 }
284
285 if(i == acquaintances.end()) {
286 return false;
287 }
288
289 acquaintances.erase(i);
290 save_acquaintances();
291
292 return true;
293 }
294
is_friend(const std::string & nick)295 bool is_friend(const std::string& nick)
296 {
297 load_acquaintances();
298 const std::map<std::string, acquaintance
299 >::const_iterator it = acquaintances.find(nick);
300
301 if(it == acquaintances.end()) {
302 return false;
303 } else {
304 return it->second.get_status() == "friend";
305 }
306 }
307
is_ignored(const std::string & nick)308 bool is_ignored(const std::string& nick)
309 {
310 load_acquaintances();
311 const std::map<std::string, acquaintance
312 >::const_iterator it = acquaintances.find(nick);
313
314 if(it == acquaintances.end()) {
315 return false;
316 } else {
317 return it->second.get_status() == "ignore";
318 }
319 }
320
add_completed_campaign(const std::string & campaign_id,const std::string & difficulty_level)321 void add_completed_campaign(const std::string &campaign_id, const std::string &difficulty_level) {
322 completed_campaigns[campaign_id].insert(difficulty_level);
323 }
324
is_campaign_completed(const std::string & campaign_id)325 bool is_campaign_completed(const std::string& campaign_id) {
326 return completed_campaigns.count(campaign_id) != 0;
327 }
328
is_campaign_completed(const std::string & campaign_id,const std::string & difficulty_level)329 bool is_campaign_completed(const std::string& campaign_id, const std::string &difficulty_level) {
330 std::map<std::string, std::set<std::string>>::iterator it = completed_campaigns.find(campaign_id);
331 return it == completed_campaigns.end() ? false : it->second.count(difficulty_level) != 0;
332 }
333
parse_should_show_lobby_join(const std::string & sender,const std::string & message)334 bool parse_should_show_lobby_join(const std::string &sender, const std::string &message)
335 {
336 // If it's actually not a lobby join or leave message return true (show it).
337 if (sender != "server") return true;
338 std::string::size_type pos = message.find(" has logged into the lobby");
339 if (pos == std::string::npos){
340 pos = message.find(" has disconnected");
341 if (pos == std::string::npos) return true;
342 }
343 int lj = lobby_joins();
344 if (lj == SHOW_NONE) return false;
345 if (lj == SHOW_ALL) return true;
346 return is_friend(message.substr(0, pos));
347 }
348
lobby_joins()349 int lobby_joins()
350 {
351 std::string pref = preferences::get("lobby_joins");
352 if (pref == "friends") {
353 return SHOW_FRIENDS;
354 } else if (pref == "all") {
355 return SHOW_ALL;
356 } else if (pref == "none") {
357 return SHOW_NONE;
358 } else {
359 return SHOW_FRIENDS;
360 }
361 }
362
363
_set_lobby_joins(int show)364 void _set_lobby_joins(int show)
365 {
366 if (show == SHOW_FRIENDS) {
367 preferences::set("lobby_joins", "friends");
368 } else if (show == SHOW_ALL) {
369 preferences::set("lobby_joins", "all");
370 } else if (show == SHOW_NONE) {
371 preferences::set("lobby_joins", "none");
372 }
373 }
374
server_list()375 const std::vector<game_config::server_info>& server_list()
376 {
377 static std::vector<game_config::server_info> pref_servers;
378 if(pref_servers.empty()) {
379 std::vector<game_config::server_info> &game_servers = game_config::server_list;
380 VALIDATE(!game_servers.empty(), _("No server has been defined."));
381 pref_servers.insert(pref_servers.begin(), game_servers.begin(), game_servers.end());
382 for(const config &server : get_prefs()->child_range("server")) {
383 game_config::server_info sinf;
384 sinf.name = server["name"].str();
385 sinf.address = server["address"].str();
386 pref_servers.push_back(sinf);
387 }
388 }
389 return pref_servers;
390 }
391
network_host()392 std::string network_host()
393 {
394 const std::string res = preferences::get("host");
395 if(res.empty()) {
396 return server_list().front().address;
397 } else {
398 return res;
399 }
400 }
401
set_network_host(const std::string & host)402 void set_network_host(const std::string& host)
403 {
404 preferences::set("host", host);
405 }
406
campaign_server()407 std::string campaign_server()
408 {
409 if(!preferences::get("campaign_server").empty()) {
410 return preferences::get("campaign_server");
411 } else {
412 return "add-ons.wesnoth.org";
413 }
414 }
415
set_campaign_server(const std::string & host)416 void set_campaign_server(const std::string& host)
417 {
418 preferences::set("campaign_server", host);
419 }
420
turn_dialog()421 bool turn_dialog()
422 {
423 return preferences::get("turn_dialog", false);
424 }
425
set_turn_dialog(bool ison)426 void set_turn_dialog(bool ison)
427 {
428 preferences::set("turn_dialog", ison);
429 }
430
enable_whiteboard_mode_on_start()431 bool enable_whiteboard_mode_on_start()
432 {
433 return preferences::get("enable_planning_mode_on_start", false);
434 }
435
set_enable_whiteboard_mode_on_start(bool value)436 void set_enable_whiteboard_mode_on_start(bool value)
437 {
438 preferences::set("enable_planning_mode_on_start", value);
439 }
440
hide_whiteboard()441 bool hide_whiteboard()
442 {
443 return preferences::get("hide_whiteboard", false);
444 }
445
set_hide_whiteboard(bool value)446 void set_hide_whiteboard(bool value)
447 {
448 preferences::set("hide_whiteboard", value);
449 }
450
show_combat()451 bool show_combat()
452 {
453 return preferences::get("show_combat", true);
454 }
455
allow_observers()456 bool allow_observers()
457 {
458 return preferences::get("allow_observers", true);
459 }
460
set_allow_observers(bool value)461 void set_allow_observers(bool value)
462 {
463 preferences::set("allow_observers", value);
464 }
465
registered_users_only()466 bool registered_users_only()
467 {
468 return preferences::get("registered_users_only", false);
469 }
470
set_registered_users_only(bool value)471 void set_registered_users_only(bool value)
472 {
473 preferences::set("registered_users_only", value);
474 }
475
shuffle_sides()476 bool shuffle_sides()
477 {
478 return preferences::get("shuffle_sides", false);
479 }
480
set_shuffle_sides(bool value)481 void set_shuffle_sides(bool value)
482 {
483 preferences::set("shuffle_sides", value);
484 }
485
random_faction_mode()486 std::string random_faction_mode(){
487 return preferences::get("random_faction_mode");
488 }
489
set_random_faction_mode(const std::string & value)490 void set_random_faction_mode(const std::string & value) {
491 preferences::set("random_faction_mode", value);
492 }
493
use_map_settings()494 bool use_map_settings()
495 {
496 return preferences::get("mp_use_map_settings", true);
497 }
498
set_use_map_settings(bool value)499 void set_use_map_settings(bool value)
500 {
501 preferences::set("mp_use_map_settings", value);
502 }
503
mp_server_warning_disabled()504 int mp_server_warning_disabled()
505 {
506 return lexical_cast_default<int>(preferences::get("mp_server_warning_disabled"), 0);
507 }
508
set_mp_server_warning_disabled(int value)509 void set_mp_server_warning_disabled(int value)
510 {
511 preferences::set("mp_server_warning_disabled", value);
512 }
513
set_mp_server_program_name(const std::string & path)514 void set_mp_server_program_name(const std::string& path)
515 {
516 if (path.empty())
517 {
518 preferences::clear("mp_server_program_name");
519 }
520 else
521 {
522 preferences::set("mp_server_program_name", path);
523 }
524 }
525
get_mp_server_program_name()526 std::string get_mp_server_program_name()
527 {
528 return preferences::get("mp_server_program_name");
529 }
530
random_start_time()531 bool random_start_time()
532 {
533 return preferences::get("mp_random_start_time", true);
534 }
535
set_random_start_time(bool value)536 void set_random_start_time(bool value)
537 {
538 preferences::set("mp_random_start_time", value);
539 }
540
fog()541 bool fog()
542 {
543 return preferences::get("mp_fog", true);
544 }
545
set_fog(bool value)546 void set_fog(bool value)
547 {
548 preferences::set("mp_fog", value);
549 }
550
shroud()551 bool shroud()
552 {
553 return preferences::get("mp_shroud", false);
554 }
555
set_shroud(bool value)556 void set_shroud(bool value)
557 {
558 preferences::set("mp_shroud", value);
559 }
560
turns()561 int turns()
562 {
563 return settings::get_turns(preferences::get("mp_turns"));
564 }
565
set_turns(int value)566 void set_turns(int value)
567 {
568 preferences::set("mp_turns", value);
569 }
570
options()571 const config& options()
572 {
573 if (options_initialized) {
574 return option_values;
575 }
576
577 if (!preferences::get_child("options")) {
578 // It may be an invalid config, which would cause problems in
579 // multiplayer_create, so let's replace it with an empty but valid
580 // config
581 option_values.clear();
582 } else {
583 option_values = preferences::get_child("options");
584 }
585
586 options_initialized = true;
587
588 return option_values;
589 }
590
set_options(const config & values)591 void set_options(const config& values)
592 {
593 preferences::set_child("options", values);
594 options_initialized = false;
595 }
596
skip_mp_replay()597 bool skip_mp_replay()
598 {
599 return preferences::get("skip_mp_replay", false);
600 }
601
set_skip_mp_replay(bool value)602 void set_skip_mp_replay(bool value)
603 {
604 preferences::set("skip_mp_replay", value);
605 }
606
blindfold_replay()607 bool blindfold_replay()
608 {
609 return preferences::get("blindfold_replay", false);
610 }
611
set_blindfold_replay(bool value)612 void set_blindfold_replay(bool value)
613 {
614 preferences::set("blindfold_replay", value);
615 }
616
countdown()617 bool countdown()
618 {
619 return preferences::get("mp_countdown", false);
620 }
621
set_countdown(bool value)622 void set_countdown(bool value)
623 {
624 preferences::set("mp_countdown", value);
625 }
626
countdown_init_time()627 int countdown_init_time()
628 {
629 return utils::clamp<int>(
630 lexical_cast_default<int>(preferences::get("mp_countdown_init_time"), 270), 0, 1500);
631 }
632
set_countdown_init_time(int value)633 void set_countdown_init_time(int value)
634 {
635 preferences::set("mp_countdown_init_time", value);
636 }
637
countdown_reservoir_time()638 int countdown_reservoir_time()
639 {
640 return utils::clamp<int>(
641 lexical_cast_default<int>(preferences::get("mp_countdown_reservoir_time"), 330), 30, 1500);
642 }
643
set_countdown_reservoir_time(int value)644 void set_countdown_reservoir_time(int value)
645 {
646 preferences::set("mp_countdown_reservoir_time", value);
647 }
648
countdown_turn_bonus()649 int countdown_turn_bonus()
650 {
651 return utils::clamp<int>(
652 lexical_cast_default<int>(preferences::get("mp_countdown_turn_bonus"), 60), 0, 300);
653 }
654
set_countdown_turn_bonus(int value)655 void set_countdown_turn_bonus(int value)
656 {
657 preferences::set("mp_countdown_turn_bonus", value);
658 }
659
countdown_action_bonus()660 int countdown_action_bonus()
661 {
662 return utils::clamp<int>(
663 lexical_cast_default<int>(preferences::get("mp_countdown_action_bonus"), 13), 0, 30);
664 }
665
set_countdown_action_bonus(int value)666 void set_countdown_action_bonus(int value)
667 {
668 preferences::set("mp_countdown_action_bonus", value);
669 }
670
village_gold()671 int village_gold()
672 {
673 return settings::get_village_gold(preferences::get("mp_village_gold"));
674 }
675
set_village_gold(int value)676 void set_village_gold(int value)
677 {
678 preferences::set("mp_village_gold", value);
679 }
680
village_support()681 int village_support()
682 {
683 return settings::get_village_support(preferences::get("mp_village_support"));
684 }
685
set_village_support(int value)686 void set_village_support(int value)
687 {
688 preferences::set("mp_village_support", std::to_string(value));
689 }
690
xp_modifier()691 int xp_modifier()
692 {
693 return settings::get_xp_modifier(preferences::get("mp_xp_modifier"));
694 }
695
set_xp_modifier(int value)696 void set_xp_modifier(int value)
697 {
698 preferences::set("mp_xp_modifier", value);
699 }
700
era()701 std::string era()
702 {
703 return preferences::get("mp_era");
704 }
705
set_era(const std::string & value)706 void set_era(const std::string& value)
707 {
708 preferences::set("mp_era", value);
709 }
710
level()711 std::string level()
712 {
713 return preferences::get("mp_level");
714 }
715
set_level(const std::string & value)716 void set_level(const std::string& value)
717 {
718 preferences::set("mp_level", value);
719 }
720
level_type()721 int level_type()
722 {
723 return lexical_cast_default<int>(preferences::get("mp_level_type"), 0);
724 }
725
set_level_type(int value)726 void set_level_type(int value)
727 {
728 preferences::set("mp_level_type", value);
729 }
730
modifications(bool mp)731 const std::vector<std::string>& modifications(bool mp)
732 {
733 if ((!mp_modifications_initialized && mp) || (!sp_modifications_initialized && !mp))
734 initialize_modifications(mp);
735
736 return mp ? mp_modifications : sp_modifications;
737 }
738
set_modifications(const std::vector<std::string> & value,bool mp)739 void set_modifications(const std::vector<std::string>& value, bool mp)
740 {
741 if (mp) {
742 preferences::set("mp_modifications", utils::join(value, ","));
743 mp_modifications_initialized = false;
744 } else {
745 preferences::set("sp_modifications", utils::join(value, ","));
746 sp_modifications_initialized = false;
747 }
748
749 }
750
skip_ai_moves()751 bool skip_ai_moves()
752 {
753 return preferences::get("skip_ai_moves", false);
754 }
755
set_skip_ai_moves(bool value)756 void set_skip_ai_moves(bool value)
757 {
758 preferences::set("skip_ai_moves", value);
759 }
760
set_show_side_colors(bool value)761 void set_show_side_colors(bool value)
762 {
763 preferences::set("show_side_colors", value);
764 }
765
show_side_colors()766 bool show_side_colors()
767 {
768 return preferences::get("show_side_colors", true);
769 }
770
set_save_replays(bool value)771 void set_save_replays(bool value)
772 {
773 preferences::set("save_replays", value);
774 }
775
save_replays()776 bool save_replays()
777 {
778 return preferences::get("save_replays", true);
779 }
780
set_delete_saves(bool value)781 void set_delete_saves(bool value)
782 {
783 preferences::set("delete_saves", value);
784 }
785
delete_saves()786 bool delete_saves()
787 {
788 return preferences::get("delete_saves", false);
789 }
790
set_ask_delete_saves(bool value)791 void set_ask_delete_saves(bool value)
792 {
793 preferences::set("ask_delete", value);
794 }
795
ask_delete_saves()796 bool ask_delete_saves()
797 {
798 return preferences::get("ask_delete", true);
799 }
800
set_interrupt_when_ally_sighted(bool value)801 void set_interrupt_when_ally_sighted(bool value)
802 {
803 preferences::set("ally_sighted_interrupts", value);
804 }
805
interrupt_when_ally_sighted()806 bool interrupt_when_ally_sighted()
807 {
808 return preferences::get("ally_sighted_interrupts", true);
809 }
810
autosavemax()811 int autosavemax()
812 {
813 return lexical_cast_default<int>(preferences::get("auto_save_max"), 10);
814 }
815
set_autosavemax(int value)816 void set_autosavemax(int value)
817 {
818 preferences::set("auto_save_max", value);
819 }
820
theme()821 std::string theme()
822 {
823 if(CVideo::get_singleton().non_interactive()) {
824 static const std::string null_theme = "null";
825 return null_theme;
826 }
827
828 std::string res = preferences::get("theme");
829 if(res.empty()) {
830 return "Default";
831 }
832
833 return res;
834 }
835
set_theme(const std::string & theme)836 void set_theme(const std::string& theme)
837 {
838 if(theme != "null") {
839 preferences::set("theme", theme);
840 }
841 }
842
show_floating_labels()843 bool show_floating_labels()
844 {
845 return preferences::get("floating_labels", true);
846 }
847
set_show_floating_labels(bool value)848 void set_show_floating_labels(bool value)
849 {
850 preferences::set("floating_labels", value);
851 }
852
message_private()853 bool message_private()
854 {
855 return message_private_on;
856 }
857
set_message_private(bool value)858 void set_message_private(bool value)
859 {
860 message_private_on = value;
861 }
862
show_haloes()863 bool show_haloes()
864 {
865 return haloes;
866 }
867
set_show_haloes(bool value)868 void set_show_haloes(bool value)
869 {
870 haloes = value;
871 preferences::set("show_haloes", value);
872 }
873
save_compression_format()874 compression::format save_compression_format()
875 {
876 const std::string& choice =
877 preferences::get("compress_saves");
878
879 // "yes" was used in 1.11.7 and earlier; the compress_saves
880 // option used to be a toggle for gzip in those versions.
881 if(choice.empty() || choice == "gzip" || choice == "yes") {
882 return compression::GZIP;
883 } else if(choice == "bzip2") {
884 return compression::BZIP2;
885 } else if(choice == "none" || choice == "no") { // see above
886 return compression::NONE;
887 } /*else*/
888
889 // In case the preferences file was created by a later version
890 // supporting some algorithm we don't; although why would anyone
891 // playing a game need more algorithms, really...
892 return compression::GZIP;
893 }
894
get_chat_timestamp(const time_t & t)895 std::string get_chat_timestamp(const time_t& t) {
896 if (chat_timestamping()) {
897 if(preferences::use_twelve_hour_clock_format() == false) {
898 return lg::get_timestamp(t, _("[%H:%M]")) + " ";
899 }
900 else {
901 return lg::get_timestamp(t, _("[%I:%M %p]")) + " ";
902 }
903 }
904 return "";
905 }
906
chat_timestamping()907 bool chat_timestamping() {
908 return preferences::get("chat_timestamp", false);
909 }
910
set_chat_timestamping(bool value)911 void set_chat_timestamping(bool value) {
912 preferences::set("chat_timestamp", value);
913 }
914
chat_lines()915 int chat_lines()
916 {
917 return lexical_cast_default<int>(preferences::get("chat_lines"), 6);
918 }
919
set_chat_lines(int lines)920 void set_chat_lines(int lines)
921 {
922 preferences::set("chat_lines", lines);
923 }
924
set_chat_message_aging(const int aging)925 void set_chat_message_aging(const int aging)
926 {
927 preferences::set("chat_message_aging", aging);
928 }
929
chat_message_aging()930 int chat_message_aging()
931 {
932 return lexical_cast_default<int>(preferences::get("chat_message_aging"), 20);
933 }
934
show_all_units_in_help()935 bool show_all_units_in_help() {
936 return preferences::get("show_all_units_in_help", false);
937 }
938
set_show_all_units_in_help(bool value)939 void set_show_all_units_in_help(bool value) {
940 preferences::set("show_all_units_in_help", value);
941 }
942
encountered_units()943 std::set<std::string> &encountered_units() {
944 return encountered_units_set;
945 }
946
encountered_terrains()947 std::set<t_translation::terrain_code> &encountered_terrains() {
948 return encountered_terrains_set;
949 }
950
custom_command()951 std::string custom_command() {
952 return preferences::get("custom_command");
953 }
954
set_custom_command(const std::string & command)955 void set_custom_command(const std::string& command) {
956 preferences::set("custom_command", command);
957 }
958
959 /**
960 * Returns a pointer to the history vector associated with given id
961 * making a new one if it doesn't exist.
962 *
963 * @todo FIXME only used for gui2. Could be used for the above histories.
964 */
get_history(const std::string & id)965 std::vector<std::string>* get_history(const std::string& id) {
966 return &history_map[id];
967 }
968
green_confirm()969 bool green_confirm()
970 {
971 std::string confirmation = preferences::get("confirm_end_turn");
972
973 if (confirmation == "green" || confirmation == "yes")
974 return true;
975 return false;
976 }
977
yellow_confirm()978 bool yellow_confirm()
979 {
980 return preferences::get("confirm_end_turn") == "yellow";
981 }
982
confirm_no_moves()983 bool confirm_no_moves()
984 {
985 //This is very non-intrusive so it is on by default
986 const std::string confirmation = preferences::get("confirm_end_turn");
987 return confirmation == "no_moves" || confirmation.empty();
988 }
989
990
encounter_recruitable_units(const std::vector<team> & teams)991 void encounter_recruitable_units(const std::vector<team>& teams){
992 for (std::vector<team>::const_iterator help_team_it = teams.begin();
993 help_team_it != teams.end(); ++help_team_it) {
994 help_team_it->log_recruitable();
995 encountered_units_set.insert(help_team_it->recruits().begin(), help_team_it->recruits().end());
996 }
997 }
998
encounter_start_units(const unit_map & units)999 void encounter_start_units(const unit_map& units){
1000 for (unit_map::const_iterator help_unit_it = units.begin();
1001 help_unit_it != units.end(); ++help_unit_it) {
1002 encountered_units_set.insert(help_unit_it->type_id());
1003 }
1004 }
1005
encounter_recallable_units(const std::vector<team> & teams)1006 static void encounter_recallable_units(const std::vector<team>& teams){
1007 for (const team& t : teams) {
1008 for (const unit_const_ptr & u : t.recall_list()) {
1009 encountered_units_set.insert(u->type_id());
1010 }
1011 }
1012 }
1013
encounter_map_terrain(const gamemap & map)1014 void encounter_map_terrain(const gamemap& map)
1015 {
1016 map.for_each_loc([&](const map_location& loc) {
1017 const t_translation::terrain_code terrain = map.get_terrain(loc);
1018 preferences::encountered_terrains().insert(terrain);
1019 for (t_translation::terrain_code t : map.underlying_union_terrain(loc)) {
1020 preferences::encountered_terrains().insert(t);
1021 }
1022 });
1023 }
1024
encounter_all_content(const game_board & gameboard_)1025 void encounter_all_content(const game_board & gameboard_) {
1026 preferences::encounter_recruitable_units(gameboard_.teams());
1027 preferences::encounter_start_units(gameboard_.units());
1028 preferences::encounter_recallable_units(gameboard_.teams());
1029 preferences::encounter_map_terrain(gameboard_.map());
1030 }
1031
load_from_config(const config & cfg)1032 void acquaintance::load_from_config(const config& cfg)
1033 {
1034 nick_ = cfg["nick"].str();
1035 status_ = cfg["status"].str();
1036 notes_ = cfg["notes"].str();
1037 }
1038
save(config & item)1039 void acquaintance::save(config& item)
1040 {
1041 item["nick"] = nick_;
1042 item["status"] = status_;
1043 item["notes"] = notes_;
1044 }
1045
1046 } // preferences namespace
1047