The Battle for Wesnoth  1.17.12+dev
general.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2022
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * @file
18  * Get and set user-preferences.
19  */
20 
21 #define GETTEXT_DOMAIN "wesnoth-lib"
22 
23 #include "preferences/general.hpp"
24 
25 #include "config.hpp"
26 #include "credentials.hpp"
27 #include "filesystem.hpp"
28 #include "game_config.hpp"
29 #include "hotkey/hotkey_item.hpp"
30 #include "lexical_cast.hpp"
31 #include "log.hpp"
32 #include "sdl/point.hpp"
33 #include "serialization/parser.hpp"
34 #include "sound.hpp"
35 #include "video.hpp"
36 #include "game_config_view.hpp"
37 
38 #include <sys/stat.h> // for setting the permissions of the preferences file
39 #ifndef _WIN32
40 #include <unistd.h>
41 #endif
42 
43 static lg::log_domain log_config("config");
44 #define ERR_CFG LOG_STREAM(err , log_config)
45 
46 static lg::log_domain log_filesystem("filesystem");
47 #define ERR_FS LOG_STREAM(err, log_filesystem)
48 
49 namespace {
50 
51 bool no_preferences_save = false;
52 
53 bool fps = false;
54 
56 }
57 
58 namespace preferences {
59 
60 /*
61  * Stores all the static, default values for certain game preferences. The values
62  * are kept here for easy modification without a lengthy rebuild.
63  *
64  * Add any variables of similar type here.
65  */
66 const int min_window_width = 800;
67 const int min_window_height = 540;
68 
69 const int def_window_width = 1280;
70 const int def_window_height = 720;
71 
72 const int max_window_width = 1920;
73 const int max_window_height = 1080;
74 
75 const int min_font_scaling = 80;
76 const int max_font_scaling = 150;
77 
78 const int min_pixel_scale = 1;
79 const int max_pixel_scale = 4;
80 
82 public:
83  virtual void handle_event(const SDL_Event &) {}
84  virtual void handle_window_event(const SDL_Event &event);
86 };
87 
89 
91 {
92  event_handler_.join_global();
93 
96 }
97 
99 {
100  event_handler_.leave_global();
101 
102  try {
103  if (no_preferences_save) return;
104 
105  // Set the 'hidden' preferences.
106  prefs["scroll_threshold"] = mouse_scroll_threshold();
107 
109  } catch (...) {}
110 }
111 
112 /*
113  * Hook for setting window state variables on window resize and maximize
114  * events. Since there is no fullscreen window event, that setter is called
115  * from the video function instead.
116  */
117 void prefs_event_handler::handle_window_event(const SDL_Event& event)
118 {
119 
120  // Safety check to make sure this is a window event
121  if (event.type != SDL_WINDOWEVENT) return;
122 
123  switch(event.window.event) {
124  case SDL_WINDOWEVENT_RESIZED:
126 
127  break;
128 
129  case SDL_WINDOWEVENT_MAXIMIZED:
130  _set_maximized(true);
131 
132  break;
133 
134  case SDL_WINDOWEVENT_RESTORED:
135  _set_maximized(fullscreen() || false);
136 
137  break;
138  }
139 }
140 
142 {
143 #ifndef _WIN32
144  bool prefs_file_existed = access(filesystem::get_prefs_file().c_str(), F_OK) == 0;
145 #endif
146 
147  try {
149  write(*prefs_file, prefs);
150  } catch(const filesystem::io_exception&) {
151  ERR_FS << "error writing to preferences file '" << filesystem::get_prefs_file() << "'";
152  }
153 
155 
156 #ifndef _WIN32
157  if(!prefs_file_existed) {
158  if(chmod(filesystem::get_prefs_file().c_str(), 0600) == -1) {
159  ERR_FS << "error setting permissions of preferences file '" << filesystem::get_prefs_file() << "'";
160  }
161  }
162 #endif
163 }
164 
165 void set(const std::string &key, bool value)
166 {
167  prefs[key] = value;
168 }
169 
170 void set(const std::string &key, int value)
171 {
172  prefs[key] = value;
173 }
174 
175 void set(const std::string &key, char const *value)
176 {
177  prefs[key] = value;
178 }
179 
180 void set(const std::string &key, const std::string &value)
181 {
182  prefs[key] = value;
183 }
184 
185 void set(const std::string &key, const config::attribute_value &value)
186 {
187  prefs[key] = value;
188 }
189 
190 void clear(const std::string& key)
191 {
192  prefs.recursive_clear_value(key);
193 }
194 
195 void set_child(const std::string& key, const config& val) {
196  prefs.clear_children(key);
197  prefs.add_child(key, val);
198 }
199 
200 const config &get_child(const std::string& key)
201 {
202  return prefs.child(key);
203 }
204 
205 void erase(const std::string& key) {
206  prefs.remove_attribute(key);
207 }
208 
209 bool have_setting(const std::string& key) {
210  return prefs.has_attribute(key);
211 }
212 
213 std::string get(const std::string& key) {
214  return prefs[key];
215 }
216 
217 std::string get(const std::string& key, const std::string& def) {
218  return prefs[key].empty() ? def : prefs[key];
219 }
220 
221 bool get(const std::string &key, bool def)
222 {
223  return prefs[key].to_bool(def);
224 }
225 
227 {
228  return prefs[key];
229 }
230 
232  no_preferences_save = true;
233 }
234 
236  config* pointer = &prefs;
237  return pointer;
238 }
239 
241  try{
242 #ifdef DEFAULT_PREFS_PATH
244  read(prefs, *stream);
245 
246  config user_prefs;
248  read(user_prefs, *stream);
249 
250  prefs.merge_with(user_prefs);
251 #else
252  prefs.clear();
254  read(prefs, *stream);
255 #endif
256  } catch(const config::error& e) {
257  ERR_CFG << "Error loading preference, message: " << e.what();
258  }
259 }
260 
261 
263  return get("show_ally_orb", game_config::show_ally_orb);
264 }
265 void set_show_ally_orb(bool show_orb) {
266  prefs["show_ally_orb"] = show_orb;
267 }
268 
270  return get("show_status_on_ally_orb", game_config::show_status_on_ally_orb);
271 }
272 void set_show_status_on_ally_orb(bool show_orb) {
273  prefs["show_status_on_ally_orb"] = show_orb;
274 }
275 
277  return get("show_enemy_orb", game_config::show_enemy_orb);
278 }
279 void set_show_enemy_orb(bool show_orb) {
280  prefs["show_enemy_orb"] = show_orb;
281 }
282 
284  return get("show_moved_orb", game_config::show_moved_orb);
285 }
286 void set_show_moved_orb(bool show_orb) {
287  prefs["show_moved_orb"] = show_orb;
288 }
289 
291  return get("show_unmoved_orb", game_config::show_unmoved_orb);
292 }
293 void set_show_unmoved_orb(bool show_orb) {
294  prefs["show_unmoved_orb"] = show_orb;
295 }
296 
298  return get("show_partial_orb", game_config::show_partial_orb);
299 }
300 void set_show_partial_orb(bool show_orb) {
301  prefs["show_partial_orb"] = show_orb;
302 }
303 
305  return get("show_disengaged_orb", game_config::show_disengaged_orb);
306 }
307 void set_show_disengaged_orb(bool show_orb) {
308  prefs["show_disengaged_orb"] = show_orb;
309 }
310 
311 static std::string fix_orb_color_name(const std::string& color) {
312  if (color.substr(0,4) == "orb_") {
313  if(color[4] >= '0' && color[4] <= '9') {
314  return color.substr(5);
315  } else {
316  return color.substr(4);
317  }
318  }
319  return color;
320 }
321 
322 std::string allied_color() {
323  std::string ally_color = get("ally_orb_color");
324  if (ally_color.empty())
326  return fix_orb_color_name(ally_color);
327 }
328 void set_allied_color(const std::string& color_id) {
329  prefs["ally_orb_color"] = color_id;
330 }
331 
332 std::string core_id() {
333  std::string core_id = get("core");
334  if (core_id.empty())
335  return "default";
336  return core_id;
337 }
338 void set_core_id(const std::string& core_id) {
339  prefs["core"] = core_id;
340 }
341 
342 std::string enemy_color() {
343  std::string enemy_color = get("enemy_orb_color");
344  if (enemy_color.empty())
346  return fix_orb_color_name(enemy_color);
347 }
348 void set_enemy_color(const std::string& color_id) {
349  prefs["enemy_orb_color"] = color_id;
350 }
351 
352 std::string moved_color() {
353  std::string moved_color = get("moved_orb_color");
354  if (moved_color.empty())
356  return fix_orb_color_name(moved_color);
357 }
358 void set_moved_color(const std::string& color_id) {
359  prefs["moved_orb_color"] = color_id;
360 }
361 
362 std::string unmoved_color() {
363  std::string unmoved_color = get("unmoved_orb_color");
364  if (unmoved_color.empty())
366  return fix_orb_color_name(unmoved_color);
367 }
368 void set_unmoved_color(const std::string& color_id) {
369  prefs["unmoved_orb_color"] = color_id;
370 }
371 
372 std::string partial_color() {
373  std::string partmoved_color = get("partial_orb_color");
374  if (partmoved_color.empty())
376  return fix_orb_color_name(partmoved_color);
377 }
378 void set_partial_color(const std::string& color_id) {
379  prefs["partial_orb_color"] = color_id;
380 }
381 
383 {
384  return get("scroll_to_action", true);
385 }
386 
387 void set_scroll_to_action(bool ison)
388 {
389  prefs["scroll_to_action"] = ison;
390 }
391 
393 {
394  const unsigned x_res = prefs["xresolution"].to_unsigned();
395  const unsigned y_res = prefs["yresolution"].to_unsigned();
396 
397  // Either resolution was unspecified, return default.
398  if(x_res == 0 || y_res == 0) {
399  return point(def_window_width, def_window_height);
400  }
401 
402  return point(
403  std::max<unsigned>(x_res, min_window_width),
404  std::max<unsigned>(y_res, min_window_height)
405  );
406 }
407 
409 {
410  // For now this has a minimum value of 1 and a maximum of 4.
411  return std::max<int>(std::min<int>(prefs["pixel_scale"].to_int(1), max_pixel_scale), min_pixel_scale);
412 }
413 
414 void set_pixel_scale(const int scale)
415 {
416  prefs["pixel_scale"] = std::clamp(scale, min_pixel_scale, max_pixel_scale);
417 }
418 
420 {
421  return get("auto_pixel_scale", true);
422 }
423 
424 void set_auto_pixel_scale(bool choice)
425 {
426  prefs["auto_pixel_scale"] = choice;
427 }
428 
429 bool maximized()
430 {
431  return get("maximized", !fullscreen());
432 }
433 
435 {
436  return get("fullscreen", true);
437 }
438 
439 bool vsync()
440 {
441  return get("vsync", true);
442 }
443 
444 void _set_resolution(const point& res)
445 {
446  preferences::set("xresolution", std::to_string(res.x));
447  preferences::set("yresolution", std::to_string(res.y));
448 }
449 
450 void _set_maximized(bool ison)
451 {
452  prefs["maximized"] = ison;
453 }
454 
455 void _set_fullscreen(bool ison)
456 {
457  prefs["fullscreen"] = ison;
458 }
459 
460 void set_vsync(bool ison)
461 {
462  prefs["vsync"] = ison;
463 }
464 
465 bool turbo()
466 {
467  if(video::headless()) {
468  return true;
469  }
470 
471  return get("turbo", false);
472 }
473 
474 void set_turbo(bool ison)
475 {
476  prefs["turbo"] = ison;
477 }
478 
479 double turbo_speed()
480 {
481  return prefs["turbo_speed"].to_double(2.0);
482 }
483 
484 void set_turbo_speed(const double speed)
485 {
486  prefs["turbo_speed"] = speed;
487 }
488 
490 {
491  // Clip at 80 because if it's too low it'll cause crashes
492  return std::max<int>(std::min<int>(prefs["font_scale"].to_int(100), max_font_scaling), min_font_scaling);
493 }
494 
496 {
497  prefs["font_scale"] = std::clamp(scale, min_font_scaling, max_font_scaling);
498 }
499 
501 {
502  return (size * font_scaling()) / 100;
503 }
504 
506 {
507  return prefs["keepalive_timeout"].to_int(10);
508 }
509 
510 void keepalive_timeout(int seconds)
511 {
512  prefs["keepalive_timeout"] = std::abs(seconds);
513 }
514 
515 bool idle_anim()
516 {
517  return get("idle_anim", true);
518 }
519 
520 void set_idle_anim(const bool ison)
521 {
522  prefs["idle_anim"] = ison;
523 }
524 
526 {
527  return prefs["idle_anim_rate"].to_double(1.0);
528 }
529 
530 void set_idle_anim_rate(const int rate)
531 {
532  prefs["idle_anim_rate"] = std::pow(2.0, -rate / 10.0);
533 }
534 
535 std::string language()
536 {
537  return prefs["locale"];
538 }
539 
540 void set_language(const std::string& s)
541 {
542  preferences::set("locale", s);
543 }
544 
545 std::string gui_theme()
546 {
547  return prefs["gui2_theme"];
548 }
549 
550 void set_gui_theme(const std::string& s)
551 {
552  preferences::set("gui2_theme", s);
553 }
554 
555 bool ellipses()
556 {
557  return get("show_side_colors", false);
558 }
559 
560 void set_ellipses(bool ison)
561 {
562  preferences::set("show_side_colors", ison);
563 }
564 
565 bool grid()
566 {
567  return get("grid", false);
568 }
569 
570 void set_grid(bool ison)
571 {
572  preferences::set("grid", ison);
573 }
574 
575 std::size_t sound_buffer_size()
576 {
577  // Sounds don't sound good on Windows unless the buffer size is 4k,
578  // but this seems to cause crashes on other systems...
579  #ifdef _WIN32
580  const std::size_t buf_size = 4096;
581  #else
582  const std::size_t buf_size = 1024;
583  #endif
584 
585  return prefs["sound_buffer_size"].to_int(buf_size);
586 }
587 
588 void save_sound_buffer_size(const std::size_t size)
589 {
590  #ifdef _WIN32
591  const char* buf_size = "4096";
592  #else
593  const char* buf_size = "1024";
594  #endif
595 
596  const std::string new_size = lexical_cast_default<std::string>(size, buf_size);
597  if (get("sound_buffer_size") == new_size)
598  return;
599 
600  preferences::set("sound_buffer_size", new_size);
601 
603 }
604 
606 {
607  return prefs["music_volume"].to_int(100);
608 }
609 
610 void set_music_volume(int vol)
611 {
612  if(music_volume() == vol) {
613  return;
614  }
615 
616  prefs["music_volume"] = vol;
618 }
619 
621 {
622  return prefs["sound_volume"].to_int(100);
623 }
624 
625 void set_sound_volume(int vol)
626 {
627  if(sound_volume() == vol) {
628  return;
629  }
630 
631  prefs["sound_volume"] = vol;
633 }
634 
636 {
637  return prefs["bell_volume"].to_int(100);
638 }
639 
640 void set_bell_volume(int vol)
641 {
642  if(bell_volume() == vol) {
643  return;
644  }
645 
646  prefs["bell_volume"] = vol;
648 }
649 
651 {
652  return prefs["UI_volume"].to_int(100);
653 }
654 
655 void set_UI_volume(int vol)
656 {
657  if(UI_volume() == vol) {
658  return;
659  }
660 
661  prefs["UI_volume"] = vol;
663 }
664 
665 unsigned int tile_size()
666 {
667  return prefs["tile_size"].to_unsigned();
668 }
669 
670 void set_tile_size(const unsigned int size)
671 {
672  prefs["tile_size"] = size;
673 }
674 
675 bool turn_bell()
676 {
677  return get("turn_bell", true);
678 }
679 
680 bool set_turn_bell(bool ison)
681 {
682  if(!turn_bell() && ison) {
683  preferences::set("turn_bell", true);
684  if(!music_on() && !sound_on() && !UI_sound_on()) {
685  if(!sound::init_sound()) {
686  preferences::set("turn_bell", false);
687  return false;
688  }
689  }
690  } else if(turn_bell() && !ison) {
691  preferences::set("turn_bell", false);
693  if(!music_on() && !sound_on() && !UI_sound_on())
695  }
696  return true;
697 }
698 
700 {
701  return get("UI_sound", true);
702 }
703 
704 bool set_UI_sound(bool ison)
705 {
706  if(!UI_sound_on() && ison) {
707  preferences::set("UI_sound", true);
708  if(!music_on() && !sound_on() && !turn_bell()) {
709  if(!sound::init_sound()) {
710  preferences::set("UI_sound", false);
711  return false;
712  }
713  }
714  } else if(UI_sound_on() && !ison) {
715  preferences::set("UI_sound", false);
717  if(!music_on() && !sound_on() && !turn_bell())
719  }
720  return true;
721 }
722 
724 {
725  return get("message_bell", true);
726 }
727 
728 bool sound_on()
729 {
730  return get("sound", true);
731 }
732 
733 bool set_sound(bool ison) {
734  if(!sound_on() && ison) {
735  preferences::set("sound", true);
736  if(!music_on() && !turn_bell() && !UI_sound_on()) {
737  if(!sound::init_sound()) {
738  preferences::set("sound", false);
739  return false;
740  }
741  }
742  } else if(sound_on() && !ison) {
743  preferences::set("sound", false);
745  if(!music_on() && !turn_bell() && !UI_sound_on())
747  }
748  return true;
749 }
750 
751 bool music_on()
752 {
753  return get("music", true);
754 }
755 
756 bool set_music(bool ison) {
757  if(!music_on() && ison) {
758  preferences::set("music", true);
759  if(!sound_on() && !turn_bell() && !UI_sound_on()) {
760  if(!sound::init_sound()) {
761  preferences::set("music", false);
762  return false;
763  }
764  }
765  else
767  } else if(music_on() && !ison) {
768  preferences::set("music", false);
769  if(!sound_on() && !turn_bell() && !UI_sound_on())
771  else
773  }
774  return true;
775 }
776 
778 {
779  return get("stop_music_in_background", false);
780 }
781 
783 {
784  preferences::set("stop_music_in_background", ison);
785 }
786 
787 namespace {
788  double scroll = 0.2;
789 }
790 
792 {
793  const int value = std::clamp<int>(lexical_cast_default<int>(get("scroll"), 50), 1, 100);
794  scroll = value/100.0;
795 
796  return value;
797 }
798 
799 void set_scroll_speed(const int new_speed)
800 {
801  prefs["scroll"] = new_speed;
802  scroll = new_speed / 100.0;
803 }
804 
806 {
807  return get("middle_click_scrolls", true);
808 }
809 
811 {
812  return get("mouse_scrolling", true);
813 }
814 
815 void enable_mouse_scroll(bool value)
816 {
817  set("mouse_scrolling", value);
818 }
819 
821 {
822  return prefs["scroll_threshold"].to_int(10);
823 }
824 
826 {
827  return preferences::get("animate_map", true);
828 }
829 
831 {
832  return preferences::get("animate_water", true);
833 }
834 
836 {
837  return preferences::get("minimap_movement_coding", true);
838 }
839 
841 {
842  set("minimap_movement_coding", !minimap_movement_coding());
843 }
844 
846 {
847  return preferences::get("minimap_terrain_coding", true);
848 }
849 
851 {
852  set("minimap_terrain_coding", !minimap_terrain_coding());
853 }
854 
856 {
857  return preferences::get("minimap_draw_units", true);
858 }
859 
861 {
862  set("minimap_draw_units", !minimap_draw_units());
863 }
864 
866 {
867  return preferences::get("minimap_draw_villages", true);
868 }
869 
871 {
872  set("minimap_draw_villages", !minimap_draw_villages());
873 }
874 
876 {
877  return preferences::get("minimap_draw_terrain", true);
878 }
879 
881 {
882  set("minimap_draw_terrain", !minimap_draw_terrain());
883 }
884 
885 void set_animate_map(bool value)
886 {
887  set("animate_map", value);
888 }
889 
890 void set_animate_water(bool value)
891 {
892  set("animate_water", value);
893 }
894 
895 bool show_fps()
896 {
897  return fps;
898 }
899 
900 void set_show_fps(bool value)
901 {
902  fps = value;
903 }
904 
906 {
907  return prefs["draw_delay"].to_int(-1);
908 }
909 
910 void set_draw_delay(int value)
911 {
912  prefs["draw_delay"] = value;
913 }
914 
916 {
917  return get("color_cursors", true);
918 }
919 
920 void _set_color_cursors(bool value)
921 {
922  preferences::set("color_cursors", value);
923 }
924 
926 {
928 }
929 
931 {
933 }
934 
936 {
938  prefs.clear_children("hotkey");
939 }
940 
941 void add_alias(const std::string &alias, const std::string &command)
942 {
943  config &alias_list = prefs.child_or_add("alias");
944  alias_list[alias] = command;
945 }
946 
947 
949 {
950  return get_child("alias");
951 }
952 
953 unsigned int sample_rate()
954 {
955  return prefs["sample_rate"].to_int(44100);
956 }
957 
958 void save_sample_rate(const unsigned int rate)
959 {
960  if (sample_rate() == rate)
961  return;
962 
963  prefs["sample_rate"] = static_cast<int>(rate);
964 
965  // If audio is open, we have to re set sample rate
967 }
968 
970 {
971  return get("confirm_load_save_from_different_version", true);
972 }
973 
975 {
976  return get("use_twelve_hour_clock_format", false);
977 }
978 
980 {
981  return get("disable_auto_moves", false);
982 }
983 
984 void set_disable_auto_moves(bool value)
985 {
986  preferences::set("disable_auto_moves", value);
987 }
988 
990 {
991  return get("damage_prediction_allow_monte_carlo_simulation", true);
992 }
993 
995 {
996  set("damage_prediction_allow_monte_carlo_simulation", value);
997 }
998 
1000 {
1001  return get("addon_manager_saved_order_name");
1002 }
1003 
1004 void set_addon_manager_saved_order_name(const std::string& value)
1005 {
1006  set("addon_manager_saved_order_name", value);
1007 }
1008 
1010 {
1011  return sort_order::get_enum(get("addon_manager_saved_order_direction")).value_or(sort_order::type::none);
1012 }
1013 
1015 {
1016  set("addon_manager_saved_order_direction", sort_order::get_string(value));
1017 }
1018 
1020 {
1021  return get("selected_achievement_group");
1022 }
1023 
1024 void set_selected_achievement_group(const std::string& content_for)
1025 {
1026  set("selected_achievement_group", content_for);
1027 }
1028 
1029 bool achievement(const std::string& content_for, const std::string& id)
1030 {
1031  for(config& ach : prefs.child_range("achievements"))
1032  {
1033  if(ach["content_for"].str() == content_for)
1034  {
1035  std::vector<std::string> ids = utils::split(ach["ids"]);
1036  return std::find(ids.begin(), ids.end(), id) != ids.end();
1037  }
1038  }
1039  return false;
1040 }
1041 
1042 void set_achievement(const std::string& content_for, const std::string& id)
1043 {
1044  for(config& ach : prefs.child_range("achievements"))
1045  {
1046  // if achievements already exist for this content and the achievement has not already been set, add it
1047  if(ach["content_for"].str() == content_for)
1048  {
1049  std::vector<std::string> ids = utils::split(ach["ids"]);
1050 
1051  if(ids.empty())
1052  {
1053  ach["ids"] = id;
1054  }
1055  else if(std::find(ids.begin(), ids.end(), id) == ids.end())
1056  {
1057  ach["ids"] = ach["ids"].str() + "," + id;
1058  }
1059  ach.remove_children("in_progress", [&id](config cfg){return cfg["id"].str() == id;});
1060  return;
1061  }
1062  }
1063 
1064  // else no achievements have been set for this content yet
1065  config ach;
1066  ach["content_for"] = content_for;
1067  ach["ids"] = id;
1068  prefs.add_child("achievements", ach);
1069 }
1070 
1071 int progress_achievement(const std::string& content_for, const std::string& id, int limit, int max_progress, int amount)
1072 {
1073  if(achievement(content_for, id))
1074  {
1075  return -1;
1076  }
1077 
1078  for(config& ach : prefs.child_range("achievements"))
1079  {
1080  // if achievements already exist for this content and the achievement has not already been set, add it
1081  if(ach["content_for"].str() == content_for)
1082  {
1083  // check if this achievement has progressed before - if so then increment it
1084  for(config& in_progress : ach.child_range("in_progress"))
1085  {
1086  if(in_progress["id"].str() == id)
1087  {
1088  in_progress["progress_at"] = std::clamp(in_progress["progress_at"].to_int() + amount, 0, std::min(limit, max_progress));
1089  return in_progress["progress_at"].to_int();
1090  }
1091  }
1092 
1093  // else this is the first time this achievement is progressing
1094  if(amount != 0)
1095  {
1096  config set_progress;
1097  set_progress["id"] = id;
1098  set_progress["progress_at"] = std::clamp(amount, 0, std::min(limit, max_progress));
1099 
1100  config& child = ach.add_child("in_progress", set_progress);
1101  return child["progress_at"].to_int();
1102  }
1103  return 0;
1104  }
1105  }
1106 
1107  // else not only has this achievement not progressed before, this is the first achievement for this achievement group to be added
1108  if(amount != 0)
1109  {
1110  config ach;
1111  config set_progress;
1112 
1113  set_progress["id"] = id;
1114  set_progress["progress_at"] = std::clamp(amount, 0, std::min(limit, max_progress));
1115 
1116  ach["content_for"] = content_for;
1117  ach["ids"] = "";
1118 
1119  config& child = ach.add_child("in_progress", set_progress);
1120  prefs.add_child("achievements", ach);
1121  return child["progress_at"].to_int();
1122  }
1123  return 0;
1124 }
1125 
1126 } // end namespace preferences
bool disable_auto_moves()
Definition: general.cpp:979
void set_turbo(bool ison)
Definition: general.cpp:474
bool set_sound(bool ison)
Definition: general.cpp:733
void set_show_enemy_orb(bool show_orb)
Definition: general.cpp:279
std::string unmoved_color()
Definition: general.cpp:362
void close_sound()
Definition: sound.cpp:495
void _set_fullscreen(bool ison)
Definition: general.cpp:455
void set_grid(bool ison)
Definition: general.cpp:570
int bell_volume()
Definition: general.cpp:635
bool turn_bell()
Definition: general.cpp:675
std::string addon_manager_saved_order_name()
Definition: general.cpp:999
bool show_unmoved_orb
void set_moved_color(const std::string &color_id)
Definition: general.cpp:358
void save_hotkeys()
Definition: general.cpp:930
bool minimap_draw_units()
Definition: general.cpp:855
const int min_window_height
Definition: general.cpp:67
void set_allied_color(const std::string &color_id)
Definition: general.cpp:328
bool show_fps()
Definition: general.cpp:895
void set_unmoved_color(const std::string &color_id)
Definition: general.cpp:368
void stop_music()
Definition: sound.cpp:557
void write_preferences()
Definition: general.cpp:141
void _set_maximized(bool ison)
Definition: general.cpp:450
int mouse_scroll_threshold()
Gets the threshold for when to scroll.
Definition: general.cpp:820
void disable_preferences_save()
Definition: general.cpp:231
void save_hotkeys(config &cfg)
Save the non-default hotkeys to the config.
bool show_status_on_ally_orb()
Definition: general.cpp:269
void set_show_unmoved_orb(bool show_orb)
Definition: general.cpp:293
Variant for storing WML attributes.
#define ERR_FS
Definition: general.cpp:47
void _set_color_cursors(bool value)
Definition: general.cpp:920
const int min_window_width
Definition: general.cpp:66
static game_config_view wrap(const config &cfg)
New lexcical_cast header.
int draw_delay()
Definition: general.cpp:905
void set_scroll_speed(const int new_speed)
Definition: general.cpp:799
bool minimap_movement_coding()
Definition: general.cpp:835
const int max_window_width
Definition: general.cpp:72
void set_UI_volume(int vol)
Definition: sound.cpp:1134
bool show_enemy_orb()
Definition: general.cpp:276
void set_idle_anim_rate(const int rate)
Definition: general.cpp:530
child_itors child_range(config_key_type key)
Definition: config.cpp:344
int scroll_speed()
Definition: general.cpp:791
bool vsync()
Definition: general.cpp:439
prefs_event_handler event_handler_
Definition: general.cpp:88
filesystem::scoped_istream istream_file(const std::string &fname, bool treat_failure_as_error)
void _set_resolution(const point &res)
Definition: general.cpp:444
void enable_mouse_scroll(bool value)
Definition: general.cpp:815
void clear(const std::string &key)
Definition: general.cpp:190
virtual void leave_global()
Definition: events.cpp:393
bool idle_anim()
Definition: general.cpp:515
bool message_bell()
Definition: general.cpp:723
std::string gui_theme()
Definition: general.cpp:545
void set_tile_size(const unsigned int size)
Definition: general.cpp:670
void stop_sound()
Definition: sound.cpp:565
void set(const std::string &key, bool value)
Definition: general.cpp:165
unsigned int sample_rate()
Definition: general.cpp:953
sort_order::type addon_manager_saved_order_direction()
Definition: general.cpp:1009
double turbo_speed()
Definition: general.cpp:479
bool confirm_load_save_from_different_version()
Definition: general.cpp:969
bool animate_water()
Definition: general.cpp:830
std::string enemy_orb_color
void set_sound_volume(int vol)
Definition: general.cpp:625
void save_credentials()
bool show_enemy_orb
Definitions for the interface to Wesnoth Markup Language (WML).
bool ellipses()
Definition: general.cpp:555
void load_base_prefs()
Definition: general.cpp:240
bool sound_on()
Definition: general.cpp:728
filesystem::scoped_ostream ostream_file(const std::string &fname, std::ios_base::openmode mode, bool create_directory)
bool show_ally_orb
bool maximized()
Definition: general.cpp:429
bool init_sound()
Definition: sound.cpp:443
void load_custom_hotkeys(const game_config_view &cfg)
Registers all hotkeys present in this config, overwriting any matching default hotkeys.
void reset_sound()
Definition: sound.cpp:526
bool minimap_draw_villages()
Definition: general.cpp:865
void write(std::ostream &out, const configr_of &cfg, unsigned int level)
Definition: parser.cpp:764
std::string ally_orb_color
void set_bell_volume(int vol)
Definition: sound.cpp:1122
std::string get(const std::string &key)
Definition: general.cpp:213
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:87
void set_enemy_color(const std::string &color_id)
Definition: general.cpp:348
void scale(size_t factor, const uint32_t *src, uint32_t *trg, int srcWidth, int srcHeight, const ScalerCfg &cfg=ScalerCfg(), int yFirst=0, int yLast=std::numeric_limits< int >::max())
Definition: xbrz.cpp:1190
#define ERR_CFG
Definition: general.cpp:44
void load_hotkeys()
Definition: general.cpp:925
void toggle_minimap_draw_units()
Definition: general.cpp:860
virtual void handle_window_event(const SDL_Event &event)
Definition: general.cpp:117
void read(config &cfg, std::istream &in, abstract_validator *validator)
Definition: parser.cpp:627
bool show_disengaged_orb()
Definition: general.cpp:304
const int min_font_scaling
Definition: general.cpp:75
void stop_UI_sound()
Definition: sound.cpp:592
bool fullscreen()
Definition: general.cpp:434
const int min_pixel_scale
Definition: general.cpp:78
void set_font_scaling(int scale)
Definition: general.cpp:495
void set_music_volume(int vol)
Definition: general.cpp:610
void play_music()
Definition: sound.cpp:617
int font_scaled(int size)
Definition: general.cpp:500
void set_vsync(bool ison)
Definition: general.cpp:460
void set_show_fps(bool value)
Definition: general.cpp:900
void set_partial_color(const std::string &color_id)
Definition: general.cpp:378
void erase(const std::string &key)
Definition: general.cpp:205
std::unique_ptr< std::istream > scoped_istream
Definition: filesystem.hpp:39
sdl_handler(sdl_handler &&)=delete
void set_show_partial_orb(bool show_orb)
Definition: general.cpp:300
bool headless()
The game is running headless.
Definition: video.cpp:143
void set_core_id(const std::string &core_id)
Definition: general.cpp:338
config::attribute_value get_as_attribute(const std::string &key)
Definition: general.cpp:226
Modify, read and display user preferences.
bool achievement(const std::string &content_for, const std::string &id)
Definition: general.cpp:1029
void toggle_minimap_draw_terrain()
Definition: general.cpp:880
bool UI_sound_on()
Definition: general.cpp:699
void set_bell_volume(int vol)
Definition: general.cpp:640
void set_stop_music_in_background(bool ison)
Definition: general.cpp:782
void set_show_status_on_ally_orb(bool show_orb)
Definition: general.cpp:272
bool animate_map()
Definition: general.cpp:825
const int max_pixel_scale
Definition: general.cpp:79
void set_idle_anim(const bool ison)
Definition: general.cpp:520
bool damage_prediction_allow_monte_carlo_simulation()
Definition: general.cpp:989
bool show_ally_orb()
Definition: general.cpp:262
void set_animate_map(bool value)
Definition: general.cpp:885
const char * what() const noexcept
Definition: exceptions.hpp:36
std::string moved_orb_color
int pixel_scale()
Definition: general.cpp:408
void set_sound_volume(int vol)
Definition: sound.cpp:1102
std::string get_default_prefs_file()
void set_show_ally_orb(bool show_orb)
Definition: general.cpp:265
void set_show_moved_orb(bool show_orb)
Definition: general.cpp:286
bool show_moved_orb()
Definition: general.cpp:283
void set_music_volume(int vol)
Definition: sound.cpp:1082
void set_draw_delay(int value)
Definition: general.cpp:910
bool show_status_on_ally_orb
void toggle_minimap_draw_villages()
Definition: general.cpp:870
const int max_font_scaling
Definition: general.cpp:76
void set_UI_volume(int vol)
Definition: general.cpp:655
void set_child(const std::string &key, const config &val)
Definition: general.cpp:195
static std::string fix_orb_color_name(const std::string &color)
Definition: general.cpp:311
std::unique_ptr< std::ostream > scoped_ostream
Definition: filesystem.hpp:40
const int def_window_width
Definition: general.cpp:69
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:215
void save_sample_rate(const unsigned int rate)
Definition: general.cpp:958
std::string allied_color()
Definition: general.cpp:322
int keepalive_timeout()
Definition: general.cpp:505
void add_alias(const std::string &alias, const std::string &command)
Definition: general.cpp:941
std::string unmoved_orb_color
double idle_anim_rate()
Definition: general.cpp:525
static constexpr std::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
Definition: enum_base.hpp:57
void clear_hotkeys()
Definition: general.cpp:935
std::string moved_color()
Definition: general.cpp:352
unsigned int tile_size()
Definition: general.cpp:665
void toggle_minimap_terrain_coding()
Definition: general.cpp:850
bool middle_click_scrolls()
Definition: general.cpp:805
An exception object used when an IO error occurs.
Definition: filesystem.hpp:48
bool stop_music_in_background()
Definition: general.cpp:777
static map_location::DIRECTION s
bool music_on()
Definition: general.cpp:751
bool use_color_cursors()
Definition: general.cpp:915
void toggle_minimap_movement_coding()
Definition: general.cpp:840
Holds a 2D point.
Definition: point.hpp:24
bool set_UI_sound(bool ison)
Definition: general.cpp:704
std::string language()
Definition: general.cpp:535
config * get_prefs()
Definition: general.cpp:235
bool show_moved_orb
Declarations for File-IO.
void stop_bell()
Definition: sound.cpp:580
void set_turbo_speed(const double speed)
Definition: general.cpp:484
void set_scroll_to_action(bool ison)
Definition: general.cpp:387
void set_ellipses(bool ison)
Definition: general.cpp:560
void save_sound_buffer_size(const std::size_t size)
Definition: general.cpp:588
const config & get_child(const std::string &key)
Definition: general.cpp:200
void reset_default_hotkeys()
Reset all hotkeys to the defaults.
config & add_child(config_key_type key)
Definition: config.cpp:514
std::size_t sound_buffer_size()
Definition: general.cpp:575
std::string core_id()
Definition: general.cpp:332
void set_language(const std::string &s)
Definition: general.cpp:540
bool grid()
Definition: general.cpp:565
int progress_achievement(const std::string &content_for, const std::string &id, int limit, int max_progress, int amount)
Increments the achievement&#39;s current progress by amount if it hasn&#39;t already been completed...
Definition: general.cpp:1071
const int def_window_height
Definition: general.cpp:70
bool mouse_scroll_enabled()
Definition: general.cpp:810
std::string partial_color()
Definition: general.cpp:372
int sound_volume()
Definition: general.cpp:620
bool have_setting(const std::string &key)
Definition: general.cpp:209
int font_scaling()
Definition: general.cpp:489
static lg::log_domain log_filesystem("filesystem")
bool minimap_draw_terrain()
Definition: general.cpp:875
std::vector< std::string > split(const config_attribute_value &val)
void set_show_disengaged_orb(bool show_orb)
Definition: general.cpp:307
void load_credentials()
bool set_music(bool ison)
Definition: general.cpp:756
Standard logging facilities (interface).
bool set_turn_bell(bool ison)
Definition: general.cpp:680
bool turbo()
Definition: general.cpp:465
point window_size()
Returns the size of the window in display units / screen coordinates.
Definition: video.cpp:414
void set_selected_achievement_group(const std::string &content_for)
Definition: general.cpp:1024
static lg::log_domain log_config("config")
bool scroll_to_action()
Definition: general.cpp:382
virtual void handle_event(const SDL_Event &)
Definition: general.cpp:83
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:193
point resolution()
Definition: general.cpp:392
#define e
bool show_partial_orb
int UI_volume()
Definition: general.cpp:650
bool show_unmoved_orb()
Definition: general.cpp:290
void set_damage_prediction_allow_monte_carlo_simulation(bool value)
Definition: general.cpp:994
std::string partial_orb_color
void set_pixel_scale(const int scale)
Definition: general.cpp:414
std::string get_prefs_file()
bool show_partial_orb()
Definition: general.cpp:297
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:60
const config & get_alias()
Definition: general.cpp:948
void set_addon_manager_saved_order_direction(sort_order::type value)
Definition: general.cpp:1014
void set_animate_water(bool value)
Definition: general.cpp:890
bool show_disengaged_orb
const int max_window_height
Definition: general.cpp:73
void set_addon_manager_saved_order_name(const std::string &value)
Definition: general.cpp:1004
virtual void join_global()
Definition: events.cpp:373
bool use_twelve_hour_clock_format()
Definition: general.cpp:974
bool auto_pixel_scale()
Definition: general.cpp:419
std::string enemy_color()
Definition: general.cpp:342
int music_volume()
Definition: general.cpp:605
void set_gui_theme(const std::string &s)
Definition: general.cpp:550
bool minimap_terrain_coding()
Definition: general.cpp:845
std::string selected_achievement_group()
Definition: general.cpp:1019
void set_auto_pixel_scale(bool choice)
Definition: general.cpp:424
void set_achievement(const std::string &content_for, const std::string &id)
Marks the specified achievement as completed.
Definition: general.cpp:1042
void set_disable_auto_moves(bool value)
Definition: general.cpp:984
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.
Definition: enum_base.hpp:46