void ScreenBranch::HandleScreenMessage( const ScreenMessage SM ) { switch( SM ) { case SM_GoToNextScreen: { CString sNextScreen = NEXT_SCREEN(m_sChoice); LOG->Trace( "Branching to '%s'", sNextScreen.c_str() ); GameCommand mc; mc.Load( 0, ParseCommands(sNextScreen) ); if( mc.m_sScreen == "" ) RageException::Throw("Metric %s::%s must set \"screen\"", m_sName.c_str(), ("NextScreen"+m_sChoice).c_str() ); mc.ApplyToAllPlayers(); } break; } }
void ScreenSelect::Init() { IDLE_COMMENT_SECONDS.Load( m_sName, "IdleCommentSeconds" ); IDLE_TIMEOUT_SECONDS.Load( m_sName, "IdleTimeoutSeconds" ); ALLOW_DISABLED_PLAYER_INPUT.Load( m_sName, "AllowDisabledPlayerInput" ); ScreenWithMenuElements::Init(); // Load messages to update on split( UPDATE_ON_MESSAGE, ",", m_asSubscribedMessages ); for( unsigned i = 0; i < m_asSubscribedMessages.size(); ++i ) MESSAGEMAN->Subscribe( this, m_asSubscribedMessages[i] ); // Subscribe to PlayerJoined, if not already. if( !MESSAGEMAN->IsSubscribedToMessage(this, Message_PlayerJoined) ) this->SubscribeToMessage( Message_PlayerJoined ); // Load choices { // Instead of using NUM_CHOICES, use a comma-separated list of choices. // Each element in the list is a choice name. This level of indirection // makes it easier to add or remove items without having to change a // bunch of indices. vector<RString> asChoiceNames; split( CHOICE_NAMES, ",", asChoiceNames, true ); for( unsigned c=0; c<asChoiceNames.size(); c++ ) { RString sChoiceName = asChoiceNames[c]; GameCommand mc; mc.ApplyCommitsScreens( false ); mc.m_sName = sChoiceName; Commands cmd = ParseCommands( CHOICE(sChoiceName) ); mc.Load( c, cmd ); m_aGameCommands.push_back( mc ); } } if(m_aGameCommands.empty()) { LuaHelpers::ReportScriptErrorFmt("Screen \"%s\" does not set any choices.", m_sName.c_str()); } }
void ScreenSelect::Init() { IDLE_COMMENT_SECONDS.Load( m_sName, "IdleCommentSeconds" ); IDLE_TIMEOUT_SECONDS.Load( m_sName, "IdleTimeoutSeconds" ); ALLOW_DISABLED_PLAYER_INPUT.Load( m_sName, "AllowDisabledPlayerInput" ); ScreenWithMenuElements::Init(); // Load messages to update on split( UPDATE_ON_MESSAGE, ",", m_asSubscribedMessages ); for( unsigned i = 0; i < m_asSubscribedMessages.size(); ++i ) MESSAGEMAN->Subscribe( this, m_asSubscribedMessages[i] ); // Subscribe to PlayerJoined, if not already. if( !MESSAGEMAN->IsSubscribedToMessage(this, Message_PlayerJoined) ) this->SubscribeToMessage( Message_PlayerJoined ); // Load choices // Allow lua as an alternative to metrics. RString choice_names= CHOICE_NAMES; if(choice_names.Left(4) == "lua,") { RString command= choice_names.Right(choice_names.size()-4); Lua* L= LUA->Get(); if(LuaHelpers::RunExpression(L, command, m_sName + "::ChoiceNames")) { if(!lua_istable(L, 1)) { LuaHelpers::ReportScriptError(m_sName + "::ChoiceNames expression did not return a table of gamecommands."); } else { size_t len= lua_objlen(L, 1); for(size_t i= 1; i <= len; ++i) { lua_rawgeti(L, 1, i); if(!lua_isstring(L, -1)) { LuaHelpers::ReportScriptErrorFmt(m_sName + "::ChoiceNames element %zu is not a string.", i); } else { RString com= SArg(-1); GameCommand mc; mc.ApplyCommitsScreens(false); mc.m_sName = ssprintf("%zu", i); Commands cmd= ParseCommands(com); mc.Load(i, cmd); m_aGameCommands.push_back(mc); } lua_pop(L, 1); } } } lua_settop(L, 0); LUA->Release(L); } else { // Instead of using NUM_CHOICES, use a comma-separated list of choices. // Each element in the list is a choice name. This level of indirection // makes it easier to add or remove items without having to change a // bunch of indices. vector<RString> asChoiceNames; split( CHOICE_NAMES, ",", asChoiceNames, true ); for( unsigned c=0; c<asChoiceNames.size(); c++ ) { RString sChoiceName = asChoiceNames[c]; GameCommand mc; mc.ApplyCommitsScreens( false ); mc.m_sName = sChoiceName; Commands cmd = ParseCommands( CHOICE(sChoiceName) ); mc.Load( c, cmd ); m_aGameCommands.push_back( mc ); } } if(m_aGameCommands.empty()) { LuaHelpers::ReportScriptErrorFmt("Screen \"%s\" does not set any choices.", m_sName.c_str()); } }
virtual void Load( OptionRowDefinition &defOut, CString sParam ) { ASSERT( sParam.size() ); if( sParam.CompareNoCase("NoteSkins")==0 ) { FillNoteSkins( defOut, sParam ); return; } else if( sParam.CompareNoCase("Steps")==0 ) { FillSteps( defOut, sParam, false ); return; } else if( sParam.CompareNoCase("StepsLocked")==0 ) { FillSteps( defOut, sParam, true ); return; } else if( sParam.CompareNoCase("Characters")==0 ) { FillCharacters( defOut, sParam ); return; } else if( sParam.CompareNoCase("Styles")==0 ) { FillStyles( defOut, sParam ); return; } else if( sParam.CompareNoCase("Groups")==0 ) { FillGroups( defOut, sParam ); return; } else if( sParam.CompareNoCase("Difficulties")==0 ) { FillDifficulties( defOut, sParam ); return; } else if( sParam.CompareNoCase("SongsInCurrentSongGroup")==0 ) { FillSongsInCurrentSongGroup( defOut, sParam ); return; } Init(); defOut.Init(); m_bUseModNameForIcon = true; defOut.name = sParam; Default.Load( -1, ParseCommands(ENTRY_DEFAULT(sParam)) ); /* Parse the basic configuration metric. */ Commands cmds = ParseCommands( ENTRY(sParam) ); if( cmds.v.size() < 1 ) RageException::Throw( "Parse error in ScreenOptionsMaster::%s", sParam.c_str() ); defOut.bOneChoiceForAllPlayers = false; const int NumCols = atoi( cmds.v[0].m_vsArgs[0] ); for( unsigned i=1; i<cmds.v.size(); i++ ) { const Command &cmd = cmds.v[i]; CString sName = cmd.GetName(); if( sName == "together" ) defOut.bOneChoiceForAllPlayers = true; else if( sName == "selectmultiple" ) defOut.selectType = SELECT_MULTIPLE; else if( sName == "selectone" ) defOut.selectType = SELECT_ONE; else if( sName == "selectnone" ) defOut.selectType = SELECT_NONE; else if( sName == "showoneinrow" ) defOut.layoutType = LAYOUT_SHOW_ONE_IN_ROW; else if( sName == "reloadrowmessages" ) { for( unsigned a=1; a<cmd.m_vsArgs.size(); a++ ) m_vsReloadRowMessages.push_back( cmd.m_vsArgs[a] ); } else if( sName == "enabledforplayers" ) { defOut.m_vEnabledForPlayers.clear(); for( unsigned a=1; a<cmd.m_vsArgs.size(); a++ ) { CString sArg = cmd.m_vsArgs[a]; PlayerNumber pn = (PlayerNumber)(atoi(sArg)-1); ASSERT( pn >= 0 && pn < NUM_PLAYERS ); defOut.m_vEnabledForPlayers.insert( pn ); } } else if( sName == "exportonchange" ) defOut.m_bExportOnChange = true; else if( sName == "broadcastonexport" ) { for( unsigned i=1; i<cmd.m_vsArgs.size(); i++ ) m_vsBroadcastOnExport.push_back( cmd.m_vsArgs[i] ); } else RageException::Throw( "Unkown row flag \"%s\"", sName.c_str() ); } for( int col = 0; col < NumCols; ++col ) { GameCommand mc; mc.Load( 0, ParseCommands(ENTRY_MODE(sParam, col)) ); /* If the row has just one entry, use the name of the row as the name of the * entry. If it has more than one, each one must be specified explicitly. */ if( mc.m_sName == "" && NumCols == 1 ) mc.m_sName = sParam; if( mc.m_sName == "" ) RageException::Throw( "List \"%s\", col %i has no name", sParam.c_str(), col ); if( !mc.IsPlayable() ) { LOG->Trace( "\"%s\" is not playable.", sParam.c_str() ); continue; } ListEntries.push_back( mc ); CString sName = mc.m_sName; CString sChoice = mc.m_sName; defOut.choices.push_back( sChoice ); } // OpenITG hack: load player-defined speed mods if (sParam == "Speed") { set<CString> additionalSet; // load anything from the machine profile first Profile *pMProf = PROFILEMAN->GetMachineProfile(); if (pMProf != NULL) { FOREACH_CONST(CString, pMProf->m_sPlayerAdditionalModifiers, mod) additionalSet.insert(*mod); } // then load anything from the players' profiles FOREACH_EnabledPlayer( pn ) { Profile *pProf = PROFILEMAN->GetProfile(pn); if (pProf == NULL) continue; FOREACH_CONST(CString, pProf->m_sPlayerAdditionalModifiers, mod) additionalSet.insert(*mod); } FOREACHS_CONST( CString, additionalSet, addit_mod ) { Regex mult("^[0-9]{1,2}(\\.[0-9]{1,2})?x$"); Regex constmod("^C[0-9]{1,4}$"); Regex mmod("^M[0-9]{1,4}$"); CString sAdditModName; if (mult.Compare(*addit_mod)) { float factor = 1.0f; sscanf(*addit_mod, "%fx", &factor); sAdditModName = ssprintf("x%.1f", factor); } else if (constmod.Compare(*addit_mod)) { unsigned bpm = 300; sscanf(*addit_mod, "C%u", &bpm); sAdditModName = ssprintf("c%u", bpm); } else if (mmod.Compare(*addit_mod)) { unsigned bpm = 600; sscanf(*addit_mod, "M%u", &bpm); sAdditModName = ssprintf("m%u", bpm); } else ASSERT(0); // how'd it get in here in the first place... GameCommand mc; mc.Load( 0, ParseCommands(CString("mod,")+*addit_mod+";name,"+sAdditModName) ); if ( !mc.IsPlayable() ) { LOG->Trace( "Additional mod \"%s\" is not playable.", addit_mod->c_str() ); continue; } ListEntries.push_back(mc); defOut.choices.push_back(mc.m_sName); }
virtual void LoadInternal( const Commands &cmds ) { ASSERT( cmds.v.size() == 1 ); const Command &command = cmds.v[0]; RString sParam = command.GetArg(1).s; ASSERT( command.m_vsArgs.size() == 2 ); ASSERT( sParam.size() != 0 ); m_bUseModNameForIcon = true; m_Def.m_sName = sParam; m_Default.Load( -1, ParseCommands(ENTRY_DEFAULT(sParam)) ); { // Parse the basic configuration metric. Commands lCmds = ParseCommands( ENTRY(sParam) ); if( lCmds.v.size() < 1 ) RageException::Throw( "Parse error in \"ScreenOptionsMaster::%s\".", sParam.c_str() ); m_Def.m_bOneChoiceForAllPlayers = false; const int NumCols = StringToInt( lCmds.v[0].m_vsArgs[0] ); for( unsigned i=1; i<lCmds.v.size(); i++ ) { const Command &cmd = lCmds.v[i]; RString sName = cmd.GetName(); if( sName == "together" ) m_Def.m_bOneChoiceForAllPlayers = true; else if( sName == "selectmultiple" ) m_Def.m_selectType = SELECT_MULTIPLE; else if( sName == "selectone" ) m_Def.m_selectType = SELECT_ONE; else if( sName == "selectnone" ) m_Def.m_selectType = SELECT_NONE; else if( sName == "showoneinrow" ) m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; else if( sName == "default" ) m_Def.m_iDefault = StringToInt( cmd.GetArg(1).s ) - 1; // match ENTRY_MODE else if( sName == "reloadrowmessages" ) { for( unsigned a=1; a<cmd.m_vsArgs.size(); a++ ) m_vsReloadRowMessages.push_back( cmd.m_vsArgs[a] ); } else if( sName == "enabledforplayers" ) { m_Def.m_vEnabledForPlayers.clear(); for( unsigned a=1; a<cmd.m_vsArgs.size(); a++ ) { RString sArg = cmd.m_vsArgs[a]; PlayerNumber pn = (PlayerNumber)(StringToInt(sArg)-1); ASSERT( pn >= 0 && pn < NUM_PLAYERS ); m_Def.m_vEnabledForPlayers.insert( pn ); } } else if( sName == "exportonchange" ) { m_Def.m_bExportOnChange = true; } else if( sName == "broadcastonexport" ) { for( unsigned j=1; j<cmd.m_vsArgs.size(); j++ ) m_vsBroadcastOnExport.push_back( cmd.m_vsArgs[j] ); } else { RageException::Throw( "Unkown row flag \"%s\".", sName.c_str() ); } } for( int col = 0; col < NumCols; ++col ) { GameCommand mc; mc.ApplyCommitsScreens( false ); mc.Load( 0, ParseCommands(ENTRY_MODE(sParam, col)) ); /* If the row has just one entry, use the name of the row as the name of the * entry. If it has more than one, each one must be specified explicitly. */ if( mc.m_sName == "" && NumCols == 1 ) mc.m_sName = sParam; if( mc.m_sName == "" ) RageException::Throw( "List \"%s\", col %i has no name.", sParam.c_str(), col ); if( !mc.IsPlayable() ) { LOG->Trace( "\"%s\" is not playable.", sParam.c_str() ); continue; } m_aListEntries.push_back( mc ); RString sName = mc.m_sName; RString sChoice = mc.m_sName; m_Def.m_vsChoices.push_back( sChoice ); } } if( m_Def.m_selectType != SELECT_MULTIPLE && m_Def.m_iDefault == -1 ) { for( unsigned e = 0; e < m_aListEntries.size(); ++e ) { const GameCommand &mc = m_aListEntries[e]; if( mc.IsZero() ) m_Def.m_iDefault = e; } } }