00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "global.hpp"
00016
00017 #include "config.hpp"
00018 #include "log.hpp"
00019 #include "gettext.hpp"
00020 #include "game_config.hpp"
00021 #include "util.hpp"
00022 #include "serialization/string_utils.hpp"
00023 #include "wesconfig.h"
00024 #ifdef HAVE_REVISION
00025 #include "revision.hpp"
00026 #endif
00027
00028 #include <cstdlib>
00029 #include <string>
00030 #include <sstream>
00031 #include <ostream>
00032
00033 #define DBG_NG LOG_STREAM(debug, engine)
00034 #define ERR_NG LOG_STREAM(err, engine)
00035
00036 namespace game_config
00037 {
00038 int base_income = 2;
00039 int village_income = 1;
00040 int poison_amount= 8;
00041 int rest_heal_amount= 2;
00042 int recall_cost = 20;
00043 int kill_experience = 8;
00044 unsigned lobby_refresh = 2000;
00045 const int gold_carryover_percentage = 80;
00046 const bool gold_carryover_add = false;
00047 const std::string version = VERSION;
00048 #ifdef REVISION
00049 const std::string revision = VERSION " (" REVISION ")";
00050 #else
00051 const std::string revision = VERSION;
00052 #endif
00053 bool debug = false, editor = false, ignore_replay_errors = false, mp_debug = false, exit_at_end = false, no_delay = false, disable_autosave = false;
00054
00055 std::string game_icon = "wesnoth-icon.png", game_title, game_logo, title_music, lobby_music;
00056 int title_logo_x = 0, title_logo_y = 0, title_buttons_x = 0, title_buttons_y = 0, title_buttons_padding = 0,
00057 title_tip_x = 0, title_tip_width = 0, title_tip_padding = 0;
00058
00059 std::string terrain_mask_image = "terrain/alphamask.png";
00060 std::string grid_image = "terrain/grid.png";
00061 std::string unreachable_image = "terrain/darken.png";
00062 std::string linger_image = "terrain/darken-linger.png";
00063
00064 std::string energy_image = "misc/bar-energy.png";
00065 std::string moved_ball_image = "misc/ball-moved.png";
00066 std::string unmoved_ball_image = "misc/ball-unmoved.png";
00067 std::string partmoved_ball_image = "misc/ball-partmoved.png";
00068 std::string enemy_ball_image = "misc/ball-enemy.png";
00069 std::string ally_ball_image = "misc/ball-ally.png";
00070 std::string flag_image = "flags/flag-1.png:150,flags/flag-2.png:150,flags/flag-3.png:150,flags/flag-4.png:150";
00071 std::string flag_icon_image = "flags/flag_icon.png";
00072 std::string flag_rgb = "flag_green";
00073 std::vector<Uint32> defense_color_scale;
00074
00075 double hp_bar_scaling = 0.666;
00076 double xp_bar_scaling = 0.5;
00077
00078 std::string cross_image = "misc/cross.png";
00079
00080 std::vector<std::string> foot_speed_prefix;
00081 std::string foot_teleport_enter = "footsteps/teleport-in.png";
00082 std::string foot_teleport_exit = "footsteps/teleport-out.png";
00083
00084 std::string observer_image = "misc/eye.png";
00085 std::string tod_bright_image = "misc/tod-bright.png";
00086 std::string unchecked_menu_image = "buttons/checkbox.png";
00087 std::string checked_menu_image = "buttons/checkbox-pressed.png";
00088 std::string wml_menu_image = "buttons/WML-custom.png";
00089
00090 std::string level_image;
00091 std::string ellipsis_image;
00092
00093 std::map<std::string, color_range > team_rgb_range;
00094 std::map<std::string, t_string > team_rgb_name;
00095
00096 std::map<std::string, std::vector<Uint32> > team_rgb_colors;
00097
00098 const struct game_version wesnoth_version(VERSION);
00099 const struct game_version min_savegame_version(MIN_SAVEGAME_VERSION);
00100 const struct game_version test_version("test");
00101
00102 const std::string observer_team_name = "observer";
00103
00104 const size_t max_loop = 65536;
00105
00106 namespace sounds {
00107 const std::string turn_bell = "bell.wav",
00108 timer_bell = "timer.wav",
00109 receive_message = "chat-1.ogg,chat-2.ogg,chat-3.ogg",
00110 receive_message_highlight = "chat-highlight.ogg",
00111 receive_message_friend = "chat-friend.ogg",
00112 receive_message_server = "receive.wav",
00113 user_arrive = "arrive.wav",
00114 user_leave = "leave.wav",
00115 game_user_arrive = "join.wav",
00116 game_user_leave = "leave.wav";
00117
00118 const std::string button_press = "button.wav",
00119 checkbox_release = "checkbox.wav",
00120 slider_adjust = "slider.wav",
00121 menu_expand = "expand.wav",
00122 menu_contract = "contract.wav",
00123 menu_select = "select.wav";
00124 }
00125
00126
00127
00128 #ifdef __AMIGAOS4__
00129 std::string path = "PROGDIR:";
00130 #else
00131 #ifdef WESNOTH_PATH
00132 std::string path = WESNOTH_PATH;
00133 #else
00134 std::string path = "";
00135 #endif
00136 #endif
00137 std::vector<server_info> server_list;
00138
00139 void load_config(const config* cfg)
00140 {
00141 if(cfg == NULL)
00142 return;
00143
00144 const config& v = *cfg;
00145
00146 base_income = lexical_cast_default<int>(v["base_income"], 2);
00147 village_income = lexical_cast_default<int>(v["village_income"], 1);
00148 poison_amount = lexical_cast_default<int>(v["poison_amount"], 8);
00149 rest_heal_amount = lexical_cast_default<int>(v["rest_heal_amount"], 2);
00150 recall_cost = lexical_cast_default<int>(v["recall_cost"], 20);
00151 kill_experience = lexical_cast_default<int>(v["kill_experience"], 8);
00152 lobby_refresh = lexical_cast_default<unsigned>(v["lobby_refresh"], 2000);
00153
00154 game_icon = v["icon"];
00155 game_title = v["title"];
00156 game_logo = v["logo"];
00157 title_music = v["title_music"];
00158 lobby_music = v["lobby_music"];
00159
00160 title_logo_x = lexical_cast_default<int>(v["logo_x"]);
00161 title_logo_y = lexical_cast_default<int>(v["logo_y"]);
00162 title_buttons_x = lexical_cast_default<int>(v["buttons_x"]);
00163 title_buttons_y = lexical_cast_default<int>(v["buttons_y"]);
00164 title_buttons_padding = lexical_cast_default<int>(v["buttons_padding"]);
00165
00166 title_tip_x = lexical_cast_default<int>(v["tip_x"]);
00167 title_tip_width = lexical_cast_default<int>(v["tip_width"]);
00168 title_tip_padding = lexical_cast_default<int>(v["tip_padding"]);
00169
00170
00171 energy_image = v["energy_image"];
00172 moved_ball_image = v["moved_ball_image"];
00173 unmoved_ball_image = v["unmoved_ball_image"];
00174 partmoved_ball_image = v["partmoved_ball_image"];
00175 enemy_ball_image = v["enemy_ball_image"];
00176 ally_ball_image = v["ally_ball_image"];
00177 flag_image = v["flag_image"];
00178 flag_icon_image = v["flag_icon_image"];
00179 cross_image = v["cross_image"];
00180
00181 hp_bar_scaling = lexical_cast_default<double>(v["hp_bar_scaling"]);
00182 xp_bar_scaling = lexical_cast_default<double>(v["xp_bar_scaling"]);
00183
00184 foot_speed_prefix = utils::split(v["footprint_prefix"]);
00185 foot_teleport_enter = v["footprint_teleport_enter"];
00186 foot_teleport_exit = v["footprint_teleport_exit"];
00187
00188 terrain_mask_image = v["terrain_mask_image"];
00189 grid_image = v["grid_image"];
00190 unreachable_image = v["unreachable_image"];
00191
00192 observer_image = v["observer_image"];
00193 tod_bright_image = v["tod_bright_image"];
00194
00195 level_image = v["level_image"];
00196 ellipsis_image = v["ellipsis_image"];
00197
00198 add_color_info(v);
00199
00200 flag_rgb = v["flag_rgb"];
00201 if( !flag_rgb.size()){
00202 flag_rgb="flag_green";
00203 }
00204 defense_color_scale = string2rgb(v["defense_color_scale"]);
00205 if (defense_color_scale.empty()) {
00206 defense_color_scale.push_back(0x00FFFF00);
00207 }
00208
00209 server_list.clear();
00210 const std::vector<config *> &servers = v.get_children("server");
00211 std::vector<config *>::const_iterator server;
00212 for(server = servers.begin(); server != servers.end(); ++server) {
00213 server_info sinf;
00214 sinf.name = (**server)["name"];
00215 sinf.address = (**server)["address"];
00216 server_list.push_back(sinf);
00217 }
00218 }
00219
00220 void add_color_info(const config& v){
00221 const config::child_list& team_colors = v.get_children("color_range");
00222 for(config::child_list::const_iterator teamC = team_colors.begin(); teamC != team_colors.end(); ++teamC) {
00223 if(!(**teamC)["id"].empty() && !(**teamC)["rgb"].empty()){
00224 std::string id = (**teamC)["id"];
00225 std::vector<Uint32> temp = string2rgb((**teamC)["rgb"]);
00226 team_rgb_range.insert(std::make_pair(id,color_range(temp)));
00227 team_rgb_name[id] = (**teamC)["name"];
00228
00229 std::vector<Uint32> tp = palette(team_rgb_range[id]);
00230 if(tp.size()){
00231 team_rgb_colors.insert(std::make_pair(id,tp));
00232
00233 DBG_NG << "color palette creation:\n";
00234 std::stringstream str;
00235 str << id <<" = ";
00236 for(std::vector<Uint32>::const_iterator r=tp.begin();r!=tp.end();r++){
00237 int red = ((*r) & 0x00FF0000)>>16;
00238 int green = ((*r) & 0x0000FF00)>>8;
00239 int blue = ((*r) & 0x000000FF);
00240 if(r!=tp.begin()) {
00241 str<<",";
00242 }
00243 str << red << "," << green << "," << blue;
00244 }
00245 DBG_NG << str.str() <<"\n";
00246 }
00247 }
00248 }
00249
00250 const config::child_list& colors = v.get_children("color_palette");
00251 for(config::child_list::const_iterator cp = colors.begin(); cp != colors.end(); ++cp) {
00252 for(string_map::const_iterator rgb_it = (*cp)->values.begin(); rgb_it != (*cp)->values.end(); ++rgb_it) {
00253 try {
00254 team_rgb_colors.insert(std::make_pair(rgb_it->first,string2rgb(rgb_it->second)));
00255 } catch(bad_lexical_cast&) {
00256
00257 ERR_NG << "Invalid team color: " << rgb_it->second << "\n";
00258 }
00259 }
00260 }
00261 }
00262
00263 const color_range& color_info(const std::string& name)
00264 {
00265 std::map<std::string, color_range>::const_iterator i = team_rgb_range.find(name);
00266 if(i == team_rgb_range.end()) {
00267 try {
00268 team_rgb_range.insert(std::make_pair(name,color_range(string2rgb(name))));
00269 return color_info(name);
00270 } catch(bad_lexical_cast&) {
00271
00272
00273 throw config::error(_("Invalid color range: ") + name);
00274 }
00275 }
00276 return i->second;
00277 }
00278
00279 const std::vector<Uint32>& tc_info(const std::string& name)
00280 {
00281 std::map<std::string, std::vector<Uint32> >::const_iterator i = team_rgb_colors.find(name);
00282 if(i == team_rgb_colors.end()) {
00283 try {
00284 team_rgb_colors.insert(std::make_pair(name,string2rgb(name)));
00285 return tc_info(name);
00286 } catch(bad_lexical_cast&) {
00287 static std::vector<Uint32> stv;
00288
00289 ERR_NG << "Invalid team color: " << name << "\n";
00290 return stv;
00291 }
00292 }
00293 return i->second;
00294 }
00295
00296 game_version::game_version(std::string str) :
00297 major_nr(0), minor_nr(0), patch(0), extra(""), full(str)
00298 {
00299
00300 size_t offset = str.find_first_not_of("0123456789");
00301 major_nr = lexical_cast_default<unsigned int>(std::string(str, 0, offset), 0);
00302 str.erase(0, offset + 1);
00303
00304 if(! str.empty()) {
00305 offset = str.find_first_not_of("0123456789");
00306 minor_nr = lexical_cast_default<unsigned int>(std::string(str, 0, offset ), 0);
00307 str.erase(0, offset + 1);
00308 }
00309
00310 if(! str.empty()) {
00311 offset = str.find_first_not_of("0123456789");
00312 patch = lexical_cast_default<unsigned int>(std::string(str, 0, offset ), 0);
00313 if(offset != std::string::npos) {
00314 extra = std::string(str, offset, std::string::npos);
00315 }
00316 }
00317 }
00318
00319 bool operator<(const struct game_version& a, const struct game_version& b)
00320 {
00321 if(a.major_nr != b.major_nr) return a.major_nr < b.major_nr;
00322 if(a.minor_nr != b.minor_nr) return a.minor_nr < b.minor_nr;
00323 return a.patch < b.patch;
00324 }
00325
00326 bool operator<=(const struct game_version& a, const struct game_version& b)
00327 {
00328 return a < b || a == b;
00329 }
00330
00331 bool operator>(const struct game_version& a, const struct game_version& b)
00332 {
00333 return !(a <= b);
00334 }
00335
00336 bool operator>=(const struct game_version& a, const struct game_version& b)
00337 {
00338 return !(a < b);
00339 }
00340
00341 bool operator==(const struct game_version& a, const struct game_version& b)
00342 {
00343 return a.full == b.full;
00344 }
00345
00346 bool operator!=(const struct game_version& a, const struct game_version& b)
00347 {
00348 return a.full != b.full;
00349 }
00350
00351 }