a56343b7e3
Remove special RTL handling as it will be done when texting shaping
611 lines
23 KiB
C++
611 lines
23 KiB
C++
//
|
|
// SuperTuxKart - a fun racing game with go-kart
|
|
// Copyright (C) 2006-2015 Joerg Henrichs
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 3
|
|
// of the License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
#include "config/stk_config.hpp"
|
|
|
|
#include <stdexcept>
|
|
#include <stdio.h>
|
|
#include <sstream>
|
|
|
|
#include "audio/music_information.hpp"
|
|
#include "io/file_manager.hpp"
|
|
#include "io/xml_node.hpp"
|
|
#include "items/item.hpp"
|
|
#include "karts/kart_properties.hpp"
|
|
#include "utils/log.hpp"
|
|
#include "utils/string_utils.hpp"
|
|
|
|
STKConfig* stk_config=0;
|
|
float STKConfig::UNDEFINED = -99.9f;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/** Constructor, which only initialises the object. The actual work is done
|
|
* by calling load().
|
|
*/
|
|
STKConfig::STKConfig()
|
|
{
|
|
m_has_been_loaded = false;
|
|
m_title_music = NULL;
|
|
m_default_kart_properties = new KartProperties();
|
|
} // STKConfig
|
|
//-----------------------------------------------------------------------------
|
|
STKConfig::~STKConfig()
|
|
{
|
|
if(m_title_music)
|
|
delete m_title_music;
|
|
|
|
if (m_default_music)
|
|
delete m_default_music;
|
|
|
|
if(m_default_kart_properties)
|
|
delete m_default_kart_properties;
|
|
|
|
for(std::map<std::string, KartProperties*>::iterator it = m_kart_properties.begin();
|
|
it != m_kart_properties.end(); ++it)
|
|
{
|
|
if (it->second)
|
|
delete it->second;
|
|
}
|
|
} // ~STKConfig
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/** Loads the stk configuration file. After loading it checks if all necessary
|
|
* values are actually defined, otherwise an error message is printed and STK
|
|
* is aborted.
|
|
* /param filename Name of the configuration file to load.
|
|
*/
|
|
void STKConfig::load(const std::string &filename)
|
|
{
|
|
// Avoid loading the default config file if a user-specific
|
|
// config file has already been loaded.
|
|
if(m_has_been_loaded) return;
|
|
m_has_been_loaded = true;
|
|
|
|
init_defaults();
|
|
|
|
XMLNode *root = 0;
|
|
try
|
|
{
|
|
root = new XMLNode(filename);
|
|
if(!root || root->getName()!="config")
|
|
{
|
|
if(root) delete root;
|
|
std::ostringstream msg;
|
|
msg << "Couldn't load config '" << filename << "': no config node.";
|
|
throw std::runtime_error(msg.str());
|
|
}
|
|
getAllData(root);
|
|
}
|
|
|
|
catch(std::exception& err)
|
|
{
|
|
Log::error("StkConfig", "FATAL ERROR while reading '%s':", filename.c_str());
|
|
Log::fatal("StkConfig", " %s", err.what());
|
|
}
|
|
delete root;
|
|
|
|
// Check that all necessary values are indeed set
|
|
// -----------------------------------------------
|
|
|
|
#define CHECK_NEG( a,strA) if(a<=UNDEFINED) { \
|
|
Log::fatal("StkConfig", "Missing default value for '%s' in '%s'.", \
|
|
strA,filename.c_str()); \
|
|
}
|
|
|
|
if(m_score_increase.size()==0)
|
|
{
|
|
Log::fatal("StkConfig", "Not or not enough scores defined in stk_config");
|
|
}
|
|
if(m_leader_intervals.size()==0)
|
|
{
|
|
Log::fatal("StkConfig", "No follow leader interval(s) defined in stk_config");
|
|
}
|
|
|
|
if(m_switch_items.size()!=Item::ITEM_LAST-Item::ITEM_FIRST+1)
|
|
{
|
|
Log::fatal("StkConfig", "Wrong number of item switches defined in stk_config");
|
|
}
|
|
|
|
if (m_client_port == 0 || m_server_port == 0 || m_server_discovery_port == 0 ||
|
|
m_client_port == m_server_port || m_client_port == m_server_discovery_port ||
|
|
m_server_port == m_server_discovery_port)
|
|
{
|
|
Log::fatal("StkConfig", "Invalid default port values.");
|
|
}
|
|
CHECK_NEG(m_max_karts, "<karts max=..." );
|
|
CHECK_NEG(m_item_switch_ticks, "item switch-time" );
|
|
CHECK_NEG(m_bubblegum_counter, "bubblegum disappear counter");
|
|
CHECK_NEG(m_explosion_impulse_objects, "explosion-impulse-objects" );
|
|
CHECK_NEG(m_max_skidmarks, "max-skidmarks" );
|
|
CHECK_NEG(m_min_kart_version, "<kart-version min...>" );
|
|
CHECK_NEG(m_max_kart_version, "<kart-version max=...>" );
|
|
CHECK_NEG(m_min_track_version, "min-track-version" );
|
|
CHECK_NEG(m_max_track_version, "max-track-version" );
|
|
CHECK_NEG(m_min_server_version, "min-server-version" );
|
|
CHECK_NEG(m_max_server_version, "max-server-version" );
|
|
CHECK_NEG(m_skid_fadeout_time, "skid-fadeout-time" );
|
|
CHECK_NEG(m_near_ground, "near-ground" );
|
|
CHECK_NEG(m_delay_finish_time, "delay-finish-time" );
|
|
CHECK_NEG(m_music_credit_time, "music-credit-time" );
|
|
CHECK_NEG(m_leader_time_per_kart, "leader time-per-kart" );
|
|
CHECK_NEG(m_penalty_ticks, "penalty-time" );
|
|
CHECK_NEG(m_max_display_news, "max-display-news" );
|
|
CHECK_NEG(m_replay_max_frames, "replay max-frames" );
|
|
CHECK_NEG(m_replay_delta_steering, "replay delta-steering" );
|
|
CHECK_NEG(m_replay_delta_speed, "replay delta-speed " );
|
|
CHECK_NEG(m_replay_dt, "replay delta-t" );
|
|
CHECK_NEG(m_minimap_size, "minimap size" );
|
|
CHECK_NEG(m_minimap_ai_icon, "minimap ai_icon" );
|
|
CHECK_NEG(m_minimap_player_icon, "minimap player_icon" );
|
|
CHECK_NEG(m_smooth_angle_limit, "physics smooth-angle-limit" );
|
|
CHECK_NEG(m_default_track_friction, "physics default-track-friction");
|
|
CHECK_NEG(m_physics_fps, "physics fps" );
|
|
CHECK_NEG(m_no_explosive_items_timeout,"powerup no-explosive-items-timeout" );
|
|
CHECK_NEG(m_max_moveable_objects, "network max-moveable-objects");
|
|
CHECK_NEG(m_network_steering_reduction,"network steering-reduction" );
|
|
CHECK_NEG(m_default_moveable_friction, "physics default-moveable-friction");
|
|
CHECK_NEG(m_solver_iterations, "physics: solver-iterations" );
|
|
CHECK_NEG(m_solver_split_impulse_thresh,"physics: solver-split-impulse-threshold");
|
|
CHECK_NEG(m_snb_min_adjust_length, "network smoothing: min-adjust-length");
|
|
CHECK_NEG(m_snb_max_adjust_length, "network smoothing: max-adjust-length");
|
|
CHECK_NEG(m_snb_min_adjust_speed, "network smoothing: min-adjust-speed");
|
|
CHECK_NEG(m_snb_max_adjust_time, "network smoothing: max-adjust-time");
|
|
CHECK_NEG(m_snb_adjust_length_threshold, "network smoothing: adjust-length-threshold");
|
|
|
|
// Square distance to make distance checks cheaper (no sqrt)
|
|
m_default_kart_properties->checkAllSet(filename);
|
|
} // load
|
|
|
|
// -----------------------------------------------------------------------------
|
|
/** Init all values with invalid defaults, which are tested later. This
|
|
* guarantees that all parameters will indeed be initialised, and helps
|
|
* finding typos.
|
|
*/
|
|
void STKConfig::init_defaults()
|
|
{
|
|
m_bomb_time = m_bomb_time_increase =
|
|
m_explosion_impulse_objects = m_music_credit_time =
|
|
m_delay_finish_time = m_skid_fadeout_time =
|
|
m_near_ground = m_solver_split_impulse_thresh =
|
|
m_smooth_angle_limit = m_default_track_friction =
|
|
m_default_moveable_friction = UNDEFINED;
|
|
m_item_switch_ticks = -100;
|
|
m_penalty_ticks = -100;
|
|
m_physics_fps = -100;
|
|
m_bubblegum_counter = -100;
|
|
m_shield_restrict_weapons = false;
|
|
m_max_karts = -100;
|
|
m_max_skidmarks = -100;
|
|
m_min_kart_version = -100;
|
|
m_max_kart_version = -100;
|
|
m_min_track_version = -100;
|
|
m_max_track_version = -100;
|
|
m_min_server_version = -100;
|
|
m_max_server_version = -100;
|
|
m_max_display_news = -100;
|
|
m_replay_max_frames = -100;
|
|
m_replay_delta_steering = -100;
|
|
m_replay_delta_speed = -100;
|
|
m_replay_dt = -100;
|
|
m_minimap_size = -100;
|
|
m_minimap_ai_icon = -100;
|
|
m_minimap_player_icon = -100;
|
|
m_donate_url = "";
|
|
m_password_reset_url = "";
|
|
m_no_explosive_items_timeout = -100.0f;
|
|
m_max_moveable_objects = -100;
|
|
m_solver_iterations = -100;
|
|
m_solver_set_flags = 0;
|
|
m_solver_reset_flags = 0;
|
|
m_network_steering_reduction = -100;
|
|
m_title_music = NULL;
|
|
m_default_music = NULL;
|
|
m_solver_split_impulse = false;
|
|
m_smooth_normals = false;
|
|
m_same_powerup_mode = POWERUP_MODE_ONLY_IF_SAME;
|
|
m_ai_acceleration = 1.0f;
|
|
m_disable_steer_while_unskid = false;
|
|
m_camera_follow_skid = false;
|
|
m_cutscene_fov = 0.61f;
|
|
m_max_skinning_bones = 1024;
|
|
m_tc_quality = 16;
|
|
m_server_discovery_port = 2757;
|
|
m_client_port = 2758;
|
|
m_server_port = 2759;
|
|
m_snb_min_adjust_length = m_snb_max_adjust_length =
|
|
m_snb_min_adjust_speed = m_snb_max_adjust_time =
|
|
m_snb_adjust_length_threshold = UNDEFINED;
|
|
|
|
m_score_increase.clear();
|
|
m_leader_intervals.clear();
|
|
m_switch_items.clear();
|
|
m_normal_ttf.clear();
|
|
m_digit_ttf.clear();
|
|
} // init_defaults
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/** Extracts the actual information from a xml file.
|
|
* \param xml Pointer to the xml data structure.
|
|
*/
|
|
void STKConfig::getAllData(const XMLNode * root)
|
|
{
|
|
// Get the values which are not part of the default KartProperties
|
|
// ---------------------------------------------------------------
|
|
if(const XMLNode *kart_node = root->getNode("kart-version"))
|
|
{
|
|
kart_node->get("min", &m_min_kart_version);
|
|
kart_node->get("max", &m_max_kart_version);
|
|
}
|
|
|
|
if(const XMLNode *node = root->getNode("track-version"))
|
|
{
|
|
node->get("min", &m_min_track_version);
|
|
node->get("max", &m_max_track_version);
|
|
}
|
|
|
|
if(const XMLNode *node = root->getNode("server-version"))
|
|
{
|
|
node->get("min", &m_min_server_version);
|
|
node->get("max", &m_max_server_version);
|
|
}
|
|
|
|
if(const XMLNode *kart_node = root->getNode("karts"))
|
|
kart_node->get("max-number", &m_max_karts);
|
|
|
|
if (const XMLNode *node = root->getNode("HardwareReportServer"))
|
|
{
|
|
node->get("url", &m_server_hardware_report);
|
|
}
|
|
|
|
if (const XMLNode *node = root->getNode("OnlineServer"))
|
|
{
|
|
node->get("url", &m_server_api);
|
|
node->get("server-version", &m_server_api_version);
|
|
}
|
|
|
|
if (const XMLNode *node = root->getNode("AddonServer"))
|
|
{
|
|
node->get("url", &m_server_addons);
|
|
node->get("allow-news-redirects", &m_allow_news_redirects);
|
|
}
|
|
|
|
if(const XMLNode *gp_node = root->getNode("grand-prix"))
|
|
{
|
|
for(unsigned int i=0; i<gp_node->getNumNodes(); i++)
|
|
{
|
|
const XMLNode *pn=gp_node->getNode(i);
|
|
int points=-1;
|
|
pn->get("points", &points);
|
|
if(points<0)
|
|
{
|
|
Log::error("StkConfig", "Incorrect GP point specification:");
|
|
Log::fatal("StkConfig", "points: %d",
|
|
points);
|
|
}
|
|
m_score_increase.push_back(points);
|
|
}
|
|
if (m_max_karts > int(gp_node->getNumNodes()))
|
|
{
|
|
Log::error("StkConfig", "Not enough grand-prix ranking nodes:");
|
|
m_score_increase.resize(m_max_karts, 0);
|
|
}
|
|
}
|
|
|
|
if(const XMLNode *leader_node= root->getNode("follow-the-leader"))
|
|
{
|
|
leader_node->get("intervals", &m_leader_intervals );
|
|
leader_node->get("time-per-kart", &m_leader_time_per_kart);
|
|
}
|
|
|
|
if (const XMLNode *physics_node= root->getNode("physics"))
|
|
{
|
|
physics_node->get("smooth-normals", &m_smooth_normals );
|
|
physics_node->get("smooth-angle-limit", &m_smooth_angle_limit );
|
|
physics_node->get("default-track-friction", &m_default_track_friction);
|
|
physics_node->get("default-moveable-friction",
|
|
&m_default_moveable_friction);
|
|
physics_node->get("fps", &m_physics_fps );
|
|
physics_node->get("solver-iterations", &m_solver_iterations );
|
|
physics_node->get("solver-split-impulse", &m_solver_split_impulse );
|
|
physics_node->get("solver-split-impulse-threshold",
|
|
&m_solver_split_impulse_thresh);
|
|
std::vector<std::string> solver_modes;
|
|
physics_node->get("solver-mode", &solver_modes );
|
|
m_solver_set_flags=0, m_solver_reset_flags = 0;
|
|
int *p;
|
|
for (auto mode : solver_modes)
|
|
{
|
|
std::string s = mode;
|
|
p = &m_solver_set_flags;
|
|
if (s[0] == '-')
|
|
{
|
|
s.erase(s.begin());
|
|
p = &m_solver_reset_flags;
|
|
}
|
|
s = StringUtils::toLowerCase(s);
|
|
if (s == "randmize_order" ) *p |= 1;
|
|
else if (s == "friction_separate" ) *p |= 2;
|
|
else if (s == "use_warmstarting" ) *p |= 4;
|
|
else if (s == "use_friction_warmstarting" ) *p |= 8;
|
|
else if (s == "use_2_friction_directions" ) *p |= 16;
|
|
else if (s == "enable_friction_direction_caching" ) *p |= 32;
|
|
else if (s == "disable_velocity_dependent_friction_direction") *p |= 64;
|
|
else if (s == "cache_friendly" ) *p |= 128;
|
|
else if (s == "simd" ) *p |= 256;
|
|
else if (s == "cuda" ) *p |= 512;
|
|
else
|
|
{
|
|
Log::fatal("STK-Config",
|
|
"Unknown option '%s' for solver-mode - ignored.",
|
|
s.c_str());
|
|
}
|
|
} // for mode in solver_modes
|
|
|
|
}
|
|
|
|
if (const XMLNode *startup_node= root->getNode("startup"))
|
|
{
|
|
float f;
|
|
startup_node->get("penalty", &f);
|
|
m_penalty_ticks = time2Ticks(f);
|
|
}
|
|
|
|
if (const XMLNode *news_node= root->getNode("news"))
|
|
{
|
|
news_node->get("max-display", &m_max_display_news);
|
|
}
|
|
|
|
if (const XMLNode *steer_node= root->getNode("steer"))
|
|
{
|
|
steer_node->get("disable-while-unskid", &m_disable_steer_while_unskid);
|
|
steer_node->get("camera-follow-skid", &m_camera_follow_skid );
|
|
}
|
|
|
|
if (const XMLNode *camera = root->getNode("camera"))
|
|
{
|
|
camera->get("fov-1", &m_camera_fov[0]);
|
|
camera->get("fov-2", &m_camera_fov[1]);
|
|
camera->get("fov-3", &m_camera_fov[2]);
|
|
camera->get("fov-4", &m_camera_fov[3]);
|
|
|
|
for (unsigned int i = 4; i < MAX_PLAYER_COUNT; i++)
|
|
{
|
|
camera->get("fov-4", &m_camera_fov[i]);
|
|
}
|
|
camera->get("cutscene-fov", &m_cutscene_fov);
|
|
}
|
|
|
|
if (const XMLNode *music_node = root->getNode("music"))
|
|
{
|
|
std::string title_music;
|
|
music_node->get("title", &title_music);
|
|
assert(title_music.size() > 0);
|
|
title_music = file_manager->getAsset(FileManager::MUSIC, title_music);
|
|
m_title_music = MusicInformation::create(title_music);
|
|
if(!m_title_music)
|
|
Log::error("StkConfig", "Cannot load title music : %s", title_music.c_str());
|
|
|
|
std::string default_music;
|
|
music_node->get("default", &default_music);
|
|
assert(default_music.size() > 0);
|
|
default_music = file_manager->getAsset(FileManager::MUSIC, default_music);
|
|
m_default_music = MusicInformation::create(default_music);
|
|
if (!m_default_music)
|
|
Log::error("StkConfig", "Cannot load default music : %s", default_music.c_str());
|
|
}
|
|
|
|
if(const XMLNode *skidmarks_node = root->getNode("skid-marks"))
|
|
{
|
|
skidmarks_node->get("max-number", &m_max_skidmarks );
|
|
skidmarks_node->get("fadeout-time", &m_skid_fadeout_time);
|
|
}
|
|
|
|
if(const XMLNode *near_ground_node = root->getNode("near-ground"))
|
|
near_ground_node->get("distance", &m_near_ground);
|
|
|
|
if(const XMLNode *delay_finish_node= root->getNode("delay-finish"))
|
|
delay_finish_node->get("time", &m_delay_finish_time);
|
|
|
|
if(const XMLNode *credits_node= root->getNode("credits"))
|
|
credits_node->get("music", &m_music_credit_time);
|
|
|
|
|
|
if(const XMLNode *bomb_node= root->getNode("bomb"))
|
|
{
|
|
bomb_node->get("time", &m_bomb_time);
|
|
bomb_node->get("time-increase", &m_bomb_time_increase);
|
|
}
|
|
|
|
if(const XMLNode *powerup_node= root->getNode("powerup"))
|
|
{
|
|
std::string s;
|
|
powerup_node->get("collect-mode", &s);
|
|
if(s=="same")
|
|
m_same_powerup_mode = POWERUP_MODE_SAME;
|
|
else if(s=="new")
|
|
m_same_powerup_mode = POWERUP_MODE_NEW;
|
|
else if(s=="only-if-same")
|
|
m_same_powerup_mode = POWERUP_MODE_ONLY_IF_SAME;
|
|
else
|
|
{
|
|
Log::warn("StkConfig", "Invalid item mode '%s' - ignored.",
|
|
s.c_str());
|
|
}
|
|
powerup_node->get("no-explosive-items-timeout",
|
|
&m_no_explosive_items_timeout);
|
|
}
|
|
|
|
if(const XMLNode *switch_node= root->getNode("switch"))
|
|
{
|
|
switch_node->get("items", &m_switch_items );
|
|
float f;
|
|
if( switch_node->get("time", &f) )
|
|
m_item_switch_ticks = stk_config->time2Ticks(f);
|
|
}
|
|
|
|
if(const XMLNode *bubblegum_node= root->getNode("bubblegum"))
|
|
{
|
|
bubblegum_node->get("disappear-counter", &m_bubblegum_counter );
|
|
bubblegum_node->get("restrict-weapons", &m_shield_restrict_weapons);
|
|
}
|
|
|
|
if(const XMLNode *explosion_node= root->getNode("explosion"))
|
|
{
|
|
explosion_node->get("impulse-objects", &m_explosion_impulse_objects);
|
|
}
|
|
|
|
if(const XMLNode *ai_node = root->getNode("ai"))
|
|
{
|
|
ai_node->get("acceleration", &m_ai_acceleration);
|
|
}
|
|
|
|
if (const XMLNode *networking_node = root->getNode("networking"))
|
|
{
|
|
networking_node->get("max-moveable-objects", &m_max_moveable_objects);
|
|
networking_node->get("steering-reduction", &m_network_steering_reduction);
|
|
}
|
|
|
|
if(const XMLNode *replay_node = root->getNode("replay"))
|
|
{
|
|
replay_node->get("delta-steering", &m_replay_delta_steering);
|
|
replay_node->get("delta-speed", &m_replay_delta_speed );
|
|
replay_node->get("delta-t", &m_replay_dt );
|
|
replay_node->get("max-frames", &m_replay_max_frames );
|
|
|
|
}
|
|
|
|
if(const XMLNode *replay_node = root->getNode("minimap"))
|
|
{
|
|
replay_node->get("size", &m_minimap_size );
|
|
replay_node->get("ai-icon", &m_minimap_ai_icon );
|
|
replay_node->get("player-icon", &m_minimap_player_icon );
|
|
}
|
|
|
|
if(const XMLNode *replay_node = root->getNode("urls"))
|
|
{
|
|
replay_node->get("donate", &m_donate_url );
|
|
replay_node->get("password-reset", &m_password_reset_url );
|
|
}
|
|
|
|
if (const XMLNode *fonts_list = root->getNode("fonts-list"))
|
|
{
|
|
fonts_list->get("normal-ttf", &m_normal_ttf);
|
|
fonts_list->get("digit-ttf", &m_digit_ttf );
|
|
fonts_list->get("color-emoji-ttf", &m_color_emoji_ttf);
|
|
}
|
|
|
|
if (const XMLNode *skinning = root->getNode("skinning"))
|
|
{
|
|
skinning->get("max-bones", &m_max_skinning_bones);
|
|
}
|
|
|
|
if (const XMLNode *tc = root->getNode("texture-compression"))
|
|
{
|
|
tc->get("quality", &m_tc_quality);
|
|
}
|
|
|
|
if (const XMLNode *np = root->getNode("network-ports"))
|
|
{
|
|
unsigned server_discovery_port = 0;
|
|
unsigned client_port = 0;
|
|
unsigned server_port = 0;
|
|
np->get("server-discovery-port", &server_discovery_port);
|
|
np->get("client-port", &client_port);
|
|
np->get("server-port", &server_port);
|
|
m_server_discovery_port = (uint16_t)server_discovery_port;
|
|
m_client_port = (uint16_t)client_port;
|
|
m_server_port = (uint16_t)server_port;
|
|
}
|
|
|
|
if (const XMLNode *ns = root->getNode("network-smoothing"))
|
|
{
|
|
ns->get("min-adjust-length", &m_snb_min_adjust_length);
|
|
ns->get("max-adjust-length", &m_snb_max_adjust_length);
|
|
ns->get("min-adjust-speed", &m_snb_min_adjust_speed);
|
|
ns->get("max-adjust-time", &m_snb_max_adjust_time);
|
|
ns->get("adjust-length-threshold", &m_snb_adjust_length_threshold);
|
|
}
|
|
|
|
if (const XMLNode* nc = root->getNode("network-capabilities"))
|
|
{
|
|
for (unsigned int i = 0; i < nc->getNumNodes(); i++)
|
|
{
|
|
const XMLNode* name = nc->getNode(i);
|
|
std::string cap;
|
|
name->get("name", &cap);
|
|
if (!cap.empty())
|
|
m_network_capabilities.insert(cap);
|
|
}
|
|
}
|
|
|
|
// Get the default KartProperties
|
|
// ------------------------------
|
|
const XMLNode *node = root -> getNode("general-kart-defaults");
|
|
if(!node)
|
|
{
|
|
std::ostringstream msg;
|
|
msg << "Couldn't load general-kart-defaults: no node.";
|
|
throw std::runtime_error(msg.str());
|
|
}
|
|
m_default_kart_properties->getAllData(node);
|
|
const XMLNode *child_node = node->getNode("kart-type");
|
|
|
|
for (unsigned int i = 0; i < child_node->getNumNodes(); ++i)
|
|
{
|
|
const XMLNode* type = child_node->getNode(i);
|
|
m_kart_properties[type->getName()] = new KartProperties();
|
|
m_kart_properties[type->getName()]->copyFrom(m_default_kart_properties);
|
|
m_kart_properties[type->getName()]->getAllData(type);
|
|
}
|
|
} // getAllData
|
|
|
|
// ----------------------------------------------------------------------------
|
|
/** Defines the points for each position for a race with a given number
|
|
* of karts.
|
|
* \param all_scores A vector which will be resized to take num_karts
|
|
* elements and which on return contains the number of points
|
|
* for each position.
|
|
* \param num_karts Number of karts.
|
|
*/
|
|
void STKConfig::getAllScores(std::vector<int> *all_scores, int num_karts)
|
|
{
|
|
std::vector<int> sorted_score_increase;
|
|
|
|
if (num_karts == 0) return;
|
|
|
|
assert(num_karts <= m_max_karts);
|
|
all_scores->resize(num_karts);
|
|
sorted_score_increase.resize(num_karts+1); //sorting function is [begin, end[
|
|
|
|
//get increase data into sorted_score_increase
|
|
for(int i=0; i<num_karts; i++)
|
|
{
|
|
sorted_score_increase[i] = m_score_increase[i];
|
|
}
|
|
|
|
std::sort (sorted_score_increase.begin(), sorted_score_increase.end());
|
|
|
|
(*all_scores)[num_karts-1] = sorted_score_increase[0]; // last position score
|
|
|
|
// Must be signed, in case that num_karts==1
|
|
for(int i=num_karts-2; i>=0; i--)
|
|
{
|
|
(*all_scores)[i] = (*all_scores)[i+1] + sorted_score_increase[num_karts-i];
|
|
}
|
|
} // getAllScores
|