//return the lowest currently unused key in the map of rects. unsigned int IBattle::GetNextFreeRectIdx() const { //check for unused allyno keys for(unsigned int i = 0; i <= GetLastRectIdx(); i++) { if(!GetStartRect(i).IsOk()) return i; } return GetNumRects(); //if all rects are in use, or no elements exist, return first possible available allyno. }
bool IBattle::LoadOptionsPreset( const std::string& name ) { const std::string preset = FixPresetName(name); if (preset.empty()) return false; //preset not found m_preset = preset; for ( unsigned int i = 0; i < LSL::OptionsWrapper::LastOption; i++) { std::map<wxString,wxString> options = sett().GetHostingPreset( TowxString(m_preset), i ); if ( (LSL::OptionsWrapper::GameOption)i != LSL::OptionsWrapper::PrivateOptions ) { for ( std::map<wxString,wxString>::const_iterator itor = options.begin(); itor != options.end(); ++itor ) { wxLogWarning( itor->first + _T(" ::: ") + itor->second ); CustomBattleOptions().setSingleOption( STD_STRING(itor->first), STD_STRING(itor->second), (LSL::OptionsWrapper::GameOption)i ); } } else { if ( !options[_T("mapname")].IsEmpty() ) { if (LSL::usync().MapExists(STD_STRING(options[_T("mapname")]))) { SetLocalMap( STD_STRING(options[_T("mapname")]) ); SendHostInfo( HI_Map ); } else if ( !ui().OnPresetRequiringMap( options[_T("mapname")] ) ) { //user didn't want to download the missing map, so set to empty to not have it tried to be loaded again options[_T("mapname")] = wxEmptyString; sett().SetHostingPreset( TowxString(m_preset), i, options ); } } for( unsigned int j = 0; j <= GetLastRectIdx(); ++j ) { if ( GetStartRect( j ).IsOk() ) RemoveStartRect(j); // remove all rects that might come from map presets } SendHostInfo( IBattle::HI_StartRects ); unsigned int rectcount = s2l( options[_T("numrects")] ); for ( unsigned int loadrect = 0; loadrect < rectcount; loadrect++) { int ally = s2l(options[_T("rect_") + TowxString(loadrect) + _T("_ally")]); if ( ally == 0 ) continue; AddStartRect( ally - 1, s2l(options[_T("rect_") + TowxString(loadrect) + _T("_left")]), s2l(options[_T("rect_") + TowxString(loadrect) + _T("_top")]), s2l(options[_T("rect_") + TowxString(loadrect) + _T("_right")]), s2l(options[_T("rect_") + TowxString(loadrect) + _T("_bottom")]) ); } SendHostInfo( HI_StartRects ); wxStringTokenizer tkr( options[_T("restrictions")], _T('\t') ); m_restricted_units.clear(); while( tkr.HasMoreTokens() ) { wxString unitinfo = tkr.GetNextToken(); RestrictUnit( STD_STRING(unitinfo.BeforeLast(_T('='))), s2l( unitinfo.AfterLast(_T('=')) ) ); } SendHostInfo( HI_Restrictions ); Update( wxFormat( _T("%d_restrictions") ) % LSL::OptionsWrapper::PrivateOptions ); } } SendHostInfo( HI_Send_All_opts ); ui().ReloadPresetList(); return true; }
void Battle::LoadMapDefaults( const wxString& mapname ) { CustomBattleOptions().setSingleOption( _T("startpostype"), sett().GetMapLastStartPosType( mapname ), OptionsWrapper::EngineOption ); SendHostInfo( wxString::Format( _T("%d_startpostype"), OptionsWrapper::EngineOption ) ); for( unsigned int i = 0; i <= GetLastRectIdx(); ++i ) if ( GetStartRect( i ).IsOk() ) RemoveStartRect(i); // remove all rects SendHostInfo( IBattle::HI_StartRects ); std::vector<Settings::SettStartBox> savedrects = sett().GetMapLastRectPreset( mapname ); for ( std::vector<Settings::SettStartBox>::iterator itor = savedrects.begin(); itor != savedrects.end(); itor++ ) { AddStartRect( itor->ally, itor->topx, itor->topy, itor->bottomx, itor->bottomy ); } SendHostInfo( IBattle::HI_StartRects ); }
void IBattle::SaveOptionsPreset( const wxString& name ) { m_preset = FixPresetName(name); if (m_preset == _T("")) m_preset = name; //new preset for ( int i = 0; i < (int)OptionsWrapper::LastOption; i++) { if ( (OptionsWrapper::GameOption)i != OptionsWrapper::PrivateOptions ) { sett().SetHostingPreset( m_preset, (OptionsWrapper::GameOption)i, CustomBattleOptions().getOptionsMap( (OptionsWrapper::GameOption)i ) ); } else { std::map<wxString,wxString> opts; opts[_T("mapname")] = GetHostMapName(); unsigned int validrectcount = 0; if ( s2l (CustomBattleOptions().getSingleValue( _T("startpostype"), OptionsWrapper::EngineOption ) ) == ST_Choose ) { unsigned int boxcount = GetLastRectIdx(); for ( unsigned int boxnum = 0; boxnum <= boxcount; boxnum++ ) { BattleStartRect rect = GetStartRect( boxnum ); if ( rect.IsOk() ) { opts[_T("rect_") + TowxString(validrectcount) + _T("_ally")] = TowxString( rect.ally + 1 ); opts[_T("rect_") + TowxString(validrectcount) + _T("_left")] = TowxString( rect.left ); opts[_T("rect_") + TowxString(validrectcount) + _T("_top")] = TowxString( rect.top ); opts[_T("rect_") + TowxString(validrectcount) + _T("_bottom")] = TowxString( rect.bottom ); opts[_T("rect_") + TowxString(validrectcount) + _T("_right")] = TowxString( rect.right ); validrectcount++; } } } opts[_T("numrects")] = TowxString( validrectcount ); wxString restrictionsstring; for ( std::map<wxString, int>::const_iterator itor = m_restricted_units.begin(); itor != m_restricted_units.end(); ++itor ) { restrictionsstring << itor->first << _T('=') << TowxString(itor->second) << _T('\t'); } opts[_T("restrictions")] = restrictionsstring; sett().SetHostingPreset( m_preset, (OptionsWrapper::GameOption)i, opts ); } } sett().SaveSettings(); ui().ReloadPresetList(); }
void Battle::SaveMapDefaults() { // save map preset wxString mapname = LoadMap().name; wxString startpostype = CustomBattleOptions().getSingleValue( _T("startpostype"), OptionsWrapper::EngineOption ); sett().SetMapLastStartPosType( mapname, startpostype); std::vector<Settings::SettStartBox> rects; for( unsigned int i = 0; i <= GetLastRectIdx(); ++i ) { BattleStartRect rect = GetStartRect( i ); if ( rect.IsOk() ) { Settings::SettStartBox box; box.ally = rect.ally; box.topx = rect.left; box.topy = rect.top; box.bottomx = rect.right; box.bottomy = rect.bottom; rects.push_back( box ); } } sett().SetMapLastRectPreset( mapname, rects ); }
void Battle::Autobalance( BalanceType balance_type, bool support_clans, bool strong_clans, int numallyteams ) { wxLogMessage(_T("Autobalancing alliances, type=%d, clans=%d, strong_clans=%d, numallyteams=%d"),balance_type, support_clans,strong_clans, numallyteams); //size_t i; //int num_alliances; std::vector<Alliance>alliances; if ( numallyteams == 0 || numallyteams == -1 ) // 0 or 1 -> use num start rects { int ally = 0; for ( unsigned int i = 0; i < GetNumRects(); ++i ) { BattleStartRect sr = GetStartRect(i); if ( sr.IsOk() ) { ally=i; alliances.push_back( Alliance( ally ) ); ally++; } } // make at least two alliances while ( alliances.size() < 2 ) { alliances.push_back( Alliance( ally ) ); ally++; } } else { for ( int i = 0; i < numallyteams; i++ ) alliances.push_back( Alliance( i ) ); } //for(i=0;i<alliances.size();++i)alliances[i].allynum=i; wxLogMessage( _T("number of alliances: %u"), alliances.size() ); std::vector<User*> players_sorted; players_sorted.reserve( GetNumUsers() ); for ( size_t i = 0; i < GetNumUsers(); ++i ) { User& usr = GetUser( i ); if ( !usr.BattleStatus().spectator ) { players_sorted.push_back( &usr ); } } // remove players in the same team so only one remains std::map< int, User*> dedupe_teams; for ( std::vector<User*>::iterator it = players_sorted.begin(); it != players_sorted.end(); it++ ) { dedupe_teams[(*it)->BattleStatus().team] = *it; } players_sorted.clear(); players_sorted.reserve( dedupe_teams.size() ); for ( std::map<int, User*>::iterator it = dedupe_teams.begin(); it != dedupe_teams.end(); it++ ) { players_sorted.push_back( it->second ); } shuffle( players_sorted ); std::map<wxString, Alliance> clan_alliances; if ( support_clans ) { for ( size_t i=0; i < players_sorted.size(); ++i ) { wxString clan = players_sorted[i]->GetClan(); if ( !clan.empty() ) { clan_alliances[clan].AddPlayer( players_sorted[i] ); } } }; if ( balance_type != balance_random ) std::sort( players_sorted.begin(), players_sorted.end(), PlayerRankCompareFunction ); if ( support_clans ) { std::map<wxString, Alliance>::iterator clan_it = clan_alliances.begin(); while ( clan_it != clan_alliances.end() ) { Alliance &clan = (*clan_it).second; // if clan is too small (only 1 clan member in battle) or too big, dont count it as clan if ( ( clan.players.size() < 2 ) || ( !strong_clans && ( clan.players.size() > ( ( players_sorted.size() + alliances.size() -1 ) / alliances.size() ) ) ) ) { wxLogMessage( _T("removing clan %s"), (*clan_it).first.c_str() ); std::map<wxString, Alliance>::iterator next = clan_it; ++next; clan_alliances.erase( clan_it ); clan_it = next; continue; } wxLogMessage( _T("Inserting clan %s"), (*clan_it).first.c_str() ); std::sort( alliances.begin(), alliances.end() ); float lowestrank = alliances[0].ranksum; int rnd_k = 1;// number of alliances with rank equal to lowestrank while ( size_t( rnd_k ) < alliances.size() ) { if ( fabs( alliances[rnd_k].ranksum - lowestrank ) > 0.01 ) break; rnd_k++; } wxLogMessage( _T("number of lowestrank alliances with same rank=%d"), rnd_k ); alliances[my_random( rnd_k )].AddAlliance( clan ); ++clan_it; } } for ( size_t i = 0; i < players_sorted.size(); ++i ) { // skip clanners, those have been added already. if ( clan_alliances.count( players_sorted[i]->GetClan() ) > 0 ) { wxLogMessage( _T("clanner already added, nick=%s"), players_sorted[i]->GetNick().c_str() ); continue; } // find alliances with lowest ranksum // insert current user into random one out of them // since performance doesnt matter here, i simply sort alliances, // then find how many alliances in beginning have lowest ranksum // note that balance player ranks range from 1 to 1.1 now // i.e. them are quasi equal // so we're essentially adding to alliance with smallest number of players, // the one with smallest ranksum. std::sort( alliances.begin(), alliances.end() ); float lowestrank = alliances[0].ranksum; int rnd_k = 1;// number of alliances with rank equal to lowestrank while ( size_t( rnd_k ) < alliances.size() ) { if ( fabs( alliances[rnd_k].ranksum - lowestrank ) > 0.01 ) break; rnd_k++; } wxLogMessage( _T("number of lowestrank alliances with same rank=%d"), rnd_k ); alliances[my_random( rnd_k )].AddPlayer( players_sorted[i] ); } UserList::user_map_t::size_type totalplayers = GetNumUsers(); for ( size_t i = 0; i < alliances.size(); ++i ) { for ( size_t j = 0; j < alliances[i].players.size(); ++j ) { ASSERT_LOGIC( alliances[i].players[j], _T("fail in Autobalance, NULL player") ); int balanceteam = alliances[i].players[j]->BattleStatus().team; wxLogMessage( _T("setting team %d to alliance %d"), balanceteam, i ); for ( size_t h = 0; h < totalplayers; h++ ) // change ally num of all players in the team { User& usr = GetUser( h ); if ( usr.BattleStatus().team == balanceteam ) ForceAlly( usr, alliances[i].allynum ); } } } }