00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "global.hpp"
00017 #include "game_config.hpp"
00018
00019 #include "color_range.hpp"
00020 #include "config.hpp"
00021 #include "foreach.hpp"
00022 #include "gettext.hpp"
00023 #include "log.hpp"
00024 #include "util.hpp"
00025 #include "version.hpp"
00026 #include "wesconfig.h"
00027 #include "serialization/string_utils.hpp"
00028 #ifdef HAVE_REVISION
00029 #include "revision.hpp"
00030 #endif
00031
00032 static lg::log_domain log_engine("engine");
00033 #define DBG_NG LOG_STREAM(debug, log_engine)
00034 #define ERR_NG LOG_STREAM(err, log_engine)
00035
00036 namespace game_config
00037 {
00038 int base_income = 2;
00039 int village_income = 1;
00040 int village_support = 1;
00041 int poison_amount= 8;
00042 int rest_heal_amount= 2;
00043 int recall_cost = 20;
00044 int kill_experience = 8;
00045 unsigned lobby_network_timer = 100;
00046 unsigned lobby_refresh = 4000;
00047 const int gold_carryover_percentage = 80;
00048 const std::string version = VERSION;
00049 #ifdef REVISION
00050 const std::string revision = VERSION " (" REVISION ")";
00051 #else
00052 const std::string revision = VERSION;
00053 #endif
00054 std::string wesnoth_program_dir;
00055 bool debug = false, editor = false, ignore_replay_errors = false, mp_debug = false, exit_at_end = false, new_syntax = false, no_delay = false, small_gui = false, disable_autosave = false;
00056
00057 int cache_compression_level = 6;
00058
00059 int title_logo_x = 0, title_logo_y = 0, title_buttons_x = 0, title_buttons_y = 0, title_buttons_padding = 0,
00060 title_tip_x = 0, title_tip_width = 0, title_tip_padding = 0;
00061
00062 std::string title_music,
00063 lobby_music,
00064 default_victory_music,
00065 default_defeat_music;
00066
00067 namespace images {
00068 std::string game_title,
00069
00070 moved_orb,
00071 unmoved_orb,
00072 partmoved_orb,
00073 enemy_orb,
00074 ally_orb,
00075 energy,
00076
00077 flag,
00078 flag_icon,
00079
00080 terrain_mask,
00081 grid_top,
00082 grid_bottom,
00083 mouseover,
00084 selected,
00085 editor_brush,
00086 unreachable,
00087 linger,
00088
00089 observer,
00090 tod_bright,
00091 tod_dark,
00092
00093 checked_menu = "buttons/checkbox-pressed.png",
00094 unchecked_menu = "buttons/checkbox.png",
00095 wml_menu = "buttons/WML-custom.png",
00096 level,
00097 ellipsis,
00098 missing;
00099 }
00100
00101 std::string shroud_prefix, fog_prefix;
00102
00103 std::string flag_rgb;
00104 std::vector<Uint32> red_green_scale;
00105 std::vector<Uint32> red_green_scale_text;
00106
00107 std::vector<Uint32> blue_white_scale;
00108 std::vector<Uint32> blue_white_scale_text;
00109
00110 double hp_bar_scaling = 0.666;
00111 double xp_bar_scaling = 0.5;
00112
00113 double hex_brightening = 1.25;
00114
00115 std::vector<std::string> foot_speed_prefix;
00116 std::string foot_teleport_enter;
00117 std::string foot_teleport_exit;
00118
00119 std::map<std::string, color_range > team_rgb_range;
00120 std::map<std::string, t_string > team_rgb_name;
00121
00122 std::map<std::string, std::vector<Uint32> > team_rgb_colors;
00123
00124 const version_info wesnoth_version(VERSION);
00125 const version_info min_savegame_version(MIN_SAVEGAME_VERSION);
00126 const std::string test_version("test");
00127
00128 const std::string observer_team_name = "observer";
00129
00130 const size_t max_loop = 65536;
00131
00132 namespace sounds {
00133 const std::string turn_bell = "bell.wav",
00134 timer_bell = "timer.wav",
00135 receive_message = "chat-1.ogg,chat-2.ogg,chat-3.ogg",
00136 receive_message_highlight = "chat-highlight.ogg",
00137 receive_message_friend = "chat-friend.ogg",
00138 receive_message_server = "receive.wav",
00139 user_arrive = "arrive.wav",
00140 user_leave = "leave.wav",
00141 game_user_arrive = "join.wav",
00142 game_user_leave = "leave.wav";
00143
00144 const std::string button_press = "button.wav",
00145 checkbox_release = "checkbox.wav",
00146 slider_adjust = "slider.wav",
00147 menu_expand = "expand.wav",
00148 menu_contract = "contract.wav",
00149 menu_select = "select.wav";
00150 }
00151
00152
00153
00154 #ifdef __AMIGAOS4__
00155 std::string path = "PROGDIR:";
00156 #else
00157 #ifdef WESNOTH_PATH
00158 std::string path = WESNOTH_PATH;
00159 #else
00160 std::string path = "";
00161 #endif
00162 #endif
00163
00164 #ifdef DEFAULT_PREFS_PATH
00165 std::string default_preferences_path = DEFAULT_PREFS_PATH;
00166 #else
00167 std::string default_preferences_path = "";
00168 #endif
00169
00170 std::string preferences_dir = "";
00171
00172 std::vector<server_info> server_list;
00173
00174 void load_config(const config &v)
00175 {
00176 base_income = v["base_income"].to_int(2);
00177 village_income = v["village_income"].to_int(1);
00178 village_support = v["village_support"].to_int(1);
00179 poison_amount = v["poison_amount"].to_int(8);
00180 rest_heal_amount = v["rest_heal_amount"].to_int(2);
00181 recall_cost = v["recall_cost"].to_int(20);
00182 kill_experience = v["kill_experience"].to_int(8);
00183 lobby_refresh = v["lobby_refresh"].to_int(2000);
00184
00185 title_music = v["title_music"].str();
00186 lobby_music = v["lobby_music"].str();
00187 default_victory_music = v["default_victory_music"].str();
00188 default_defeat_music = v["default_defeat_music"].str();
00189
00190 if(const config &i = v.child("images")){
00191 using namespace game_config::images;
00192 game_title = i["game_title"].str();
00193
00194 moved_orb = i["moved_orb"].str();
00195 unmoved_orb = i["unmoved_orb"].str();
00196 partmoved_orb = i["partmoved_orb"].str();
00197 enemy_orb = i["enemy_orb"].str();
00198 ally_orb = i["ally_orb"].str();
00199 energy = i["energy"].str();
00200
00201 flag = i["flag"].str();
00202 flag_icon = i["flag_icon"].str();
00203
00204 terrain_mask = i["terrain_mask"].str();
00205 grid_top = i["grid_top"].str();
00206 grid_bottom = i["grid_bottom"].str();
00207 mouseover = i["mouseover"].str();
00208 selected = i["selected"].str();
00209 editor_brush = i["editor_brush"].str();
00210 unreachable = i["unreachable"].str();
00211 linger = i["linger"].str();
00212
00213 observer = i["observer"].str();
00214 tod_bright = i["tod_bright"].str();
00215 tod_dark = i["tod_dark"].str();
00216 level = i["level"].str();
00217 ellipsis = i["ellipsis"].str();
00218 missing = i["missing"].str();
00219 }
00220
00221 hp_bar_scaling = v["hp_bar_scaling"].to_double(0.666);
00222 xp_bar_scaling = v["xp_bar_scaling"].to_double(0.5);
00223 hex_brightening = v["hex_brightening"].to_double(1.25);
00224
00225 foot_speed_prefix = utils::split(v["footprint_prefix"]);
00226 foot_teleport_enter = v["footprint_teleport_enter"].str();
00227 foot_teleport_exit = v["footprint_teleport_exit"].str();
00228
00229 shroud_prefix = v["shroud_prefix"].str();
00230 fog_prefix = v["fog_prefix"].str();
00231
00232 add_color_info(v);
00233
00234 if (const config::attribute_value *a = v.get("flag_rgb"))
00235 flag_rgb = a->str();
00236
00237 std::string color_string = v["red_green_scale"].str();
00238 if(!string2rgb(color_string, red_green_scale)) {
00239 ERR_NG << "can't parse color string red_green_scale, ignoring: " << color_string << "\n";
00240 }
00241 if (red_green_scale.empty()) {
00242 red_green_scale.push_back(0x00FFFF00);
00243 }
00244
00245 color_string = v["red_green_scale_text"].str();
00246 if(!string2rgb(color_string, red_green_scale_text)) {
00247 ERR_NG << "can't parse color string red_green_scale_text, ignoring: " << color_string << "\n";
00248 }
00249 if (red_green_scale_text.empty()) {
00250 red_green_scale_text.push_back(0x00FFFF00);
00251 }
00252
00253 color_string = v["blue_white_scale"].str();
00254 if(!string2rgb(color_string, blue_white_scale)) {
00255 ERR_NG << "can't parse color string blue_white_scale, ignoring: " << color_string << "\n";
00256 }
00257 if (blue_white_scale.empty()) {
00258 blue_white_scale.push_back(0x00FFFFFF);
00259 }
00260
00261 color_string = v["blue_white_scale_text"].str();
00262 if(!string2rgb(color_string, blue_white_scale_text)) {
00263 ERR_NG << "can't parse color string blue_white_scale_text, ignoring: " << color_string << "\n";
00264 }
00265 if (blue_white_scale_text.empty()) {
00266 blue_white_scale_text.push_back(0x00FFFFFF);
00267 }
00268
00269 server_list.clear();
00270 foreach (const config &server, v.child_range("server"))
00271 {
00272 server_info sinf;
00273 sinf.name = server["name"].str();
00274 sinf.address = server["address"].str();
00275 server_list.push_back(sinf);
00276 }
00277 }
00278
00279 void add_color_info(const config &v)
00280 {
00281 foreach (const config &teamC, v.child_range("color_range"))
00282 {
00283 const config::attribute_value *a1 = teamC.get("id"),
00284 *a2 = teamC.get("rgb");
00285 if (!a1 || !a2) continue;
00286 std::string id = *a1;
00287 std::vector<Uint32> temp;
00288 if(!string2rgb(*a2, temp)) {
00289 std::stringstream ss;
00290 ss << "can't parse color string:\n" << teamC.debug() << "\n";
00291 throw config::error(ss.str());
00292 }
00293 team_rgb_range.insert(std::make_pair(id,color_range(temp)));
00294 team_rgb_name[id] = teamC["name"];
00295
00296 std::vector<Uint32> tp = palette(team_rgb_range[id]);
00297 if (tp.empty()) continue;
00298 team_rgb_colors.insert(std::make_pair(id,tp));
00299
00300 DBG_NG << "color palette creation:\n";
00301 std::ostringstream str;
00302 str << id << " = ";
00303 for (std::vector<Uint32>::const_iterator r = tp.begin(),
00304 r_end = tp.end(), r_beg = r; r != r_end; ++r)
00305 {
00306 int red = ((*r) & 0x00FF0000) >> 16;
00307 int green = ((*r) & 0x0000FF00) >> 8;
00308 int blue = ((*r) & 0x000000FF);
00309 if (r != r_beg) str << ',';
00310 str << red << ',' << green << ',' << blue;
00311 }
00312 DBG_NG << str.str() << '\n';
00313 }
00314
00315 foreach (const config &cp, v.child_range("color_palette"))
00316 {
00317 foreach (const config::attribute &rgb, cp.attribute_range())
00318 {
00319 std::vector<Uint32> temp;
00320 if(!string2rgb(rgb.second, temp)) {
00321 ERR_NG << "Invalid team color: " << rgb.second << "\n";
00322 }
00323 team_rgb_colors.insert(std::make_pair(rgb.first, temp));
00324 }
00325 }
00326 }
00327
00328 const color_range& color_info(const std::string& name)
00329 {
00330 std::map<std::string, color_range>::const_iterator i = team_rgb_range.find(name);
00331 if(i == team_rgb_range.end()) {
00332 std::vector<Uint32> temp;
00333 if(!string2rgb(name, temp))
00334 throw config::error(_("Invalid color range: ") + name);
00335 team_rgb_range.insert(std::make_pair(name,color_range(temp)));
00336 return color_info(name);
00337 }
00338 return i->second;
00339 }
00340
00341 const std::vector<Uint32>& tc_info(const std::string& name)
00342 {
00343 std::map<std::string, std::vector<Uint32> >::const_iterator i = team_rgb_colors.find(name);
00344 if(i == team_rgb_colors.end()) {
00345 std::vector<Uint32> temp;
00346 if(!string2rgb(name, temp)) {
00347 static std::vector<Uint32> stv;
00348 ERR_NG << "Invalid team color: " << name << "\n";
00349 return stv;
00350 }
00351 team_rgb_colors.insert(std::make_pair(name,temp));
00352 return tc_info(name);
00353 }
00354 return i->second;
00355 }
00356
00357 Uint32 red_to_green(int val, bool for_text){
00358 const std::vector<Uint32>& color_scale =
00359 for_text ? red_green_scale_text : red_green_scale;
00360 val = std::max<int>(0, std::min<int>(val, 100));
00361 int lvl = (color_scale.size()-1) * val / 100;
00362 return color_scale[lvl];
00363 }
00364
00365 Uint32 blue_to_white(int val, bool for_text){
00366 const std::vector<Uint32>& color_scale =
00367 for_text ? blue_white_scale_text : blue_white_scale;
00368 val = std::max<int>(0, std::min<int>(val, 100));
00369 int lvl = (color_scale.size()-1) * val / 100;
00370 return color_scale[lvl];
00371 }
00372
00373 }