Beispiel #1
0
static void SearchForDifficulty( RString sTag, Steps *pOut )
{
	sTag.MakeLower();

	// Only match "Light" in parentheses.
	if( sTag.find( "(light" ) != sTag.npos )
	{
		pOut->SetDifficulty( Difficulty_Easy );
	}
	else if( sTag.find( "another" ) != sTag.npos )
	{
		pOut->SetDifficulty( Difficulty_Hard );
	}
	else if( sTag.find( "(solo)" ) != sTag.npos )
	{
		pOut->SetDescription( "Solo" );
		pOut->SetDifficulty( Difficulty_Edit );
	}

	LOG->Trace( "Tag \"%s\" is %s", sTag.c_str(), DifficultyToString(pOut->GetDifficulty()).c_str() );
}
Beispiel #2
0
void Steps::Decompress()
{
	if( m_bNoteDataIsFilled )
		return;	// already decompressed

	if( parent )
	{
		// get autogen m_pNoteData
		NoteData notedata;
		parent->GetNoteData( notedata );

		m_bNoteDataIsFilled = true;

		int iNewTracks = GAMEMAN->GetStepsTypeInfo(m_StepsType).iNumTracks;

		if( this->m_StepsType == StepsType_lights_cabinet )
		{
			NoteDataUtil::LoadTransformedLights( notedata, *m_pNoteData, iNewTracks );
		}
		else
		{
			// Special case so that kickbox can have autogen steps that are playable.
			// Hopefully I'll replace this with a good generalized autogen system
			// later.  -Kyz
			if(stepstype_is_kickbox(this->m_StepsType))
			{
				// Number of notes seems like a useful "random" input so that charts
				// from different sources come out different, but autogen always
				// makes the same thing from one source. -Kyz
				NoteDataUtil::AutogenKickbox(notedata, *m_pNoteData, *GetTimingData(),
					this->m_StepsType,
					static_cast<int>(GetRadarValues(PLAYER_1)[RadarCategory_TapsAndHolds]));
			}
			else
			{
				NoteDataUtil::LoadTransformedSlidingWindow( notedata, *m_pNoteData, iNewTracks );

				NoteDataUtil::RemoveStretch( *m_pNoteData, m_StepsType );
			}
		}
		return;
	}

	if( !m_sFilename.empty() && m_sNoteDataCompressed.empty() )
	{
		// We have NoteData on disk and not in memory. Load it.
		if (!this->GetNoteDataFromSimfile())
		{
			LOG->Warn("Couldn't load the %s chart's NoteData from \"%s\"",
					  DifficultyToString(m_Difficulty).c_str(), m_sFilename.c_str());
			return;
		}

		this->GetSMNoteData( m_sNoteDataCompressed );
	}

	if( m_sNoteDataCompressed.empty() )
	{
		/* there is no data, do nothing */
	}
	else
	{
		// load from compressed
		bool bComposite = GAMEMAN->GetStepsTypeInfo(m_StepsType).m_StepsTypeCategory == StepsTypeCategory_Routine;
		m_bNoteDataIsFilled = true;
		m_pNoteData->SetNumTracks( GAMEMAN->GetStepsTypeInfo(m_StepsType).iNumTracks );

		NoteDataUtil::LoadFromSMNoteDataString( *m_pNoteData, m_sNoteDataCompressed, bComposite );
	}
}
ScreenRanking::ScreenRanking( CString sClassName ) : ScreenAttract( sClassName )
{
	// init Actors for category and course
	{
		m_Banner.SetName( "Banner" );
		m_Banner.SetHidden( true );
		this->AddChild( &m_Banner );

		m_sprBannerFrame.SetName( "BannerFrame" );
		m_sprBannerFrame.SetHidden( true );
		this->AddChild( &m_sprBannerFrame );

		m_textCategory.SetName( "Category" );
		m_textCategory.LoadFromFont( THEME->GetPathToF("ScreenRanking category") );
		m_textCategory.SetShadowLength( 0 );
		m_textCategory.SetHidden( true );
		this->AddChild( &m_textCategory );

		m_textCourseTitle.SetName( "CourseTitle" );
		m_textCourseTitle.LoadFromFont( THEME->GetPathToF("ScreenRanking course title") );
		m_textCourseTitle.SetShadowLength( 0 );
		m_textCourseTitle.SetHidden( true );
		this->AddChild( &m_textCourseTitle );

		m_textStepsType.SetName( "StepsType" );
		m_textStepsType.LoadFromFont( THEME->GetPathToF("ScreenRanking steps type") );
		m_textStepsType.SetShadowLength( 0 );
		m_textStepsType.SetHidden( true );
		this->AddChild( &m_textStepsType );


		for( int l=0; l<NUM_RANKING_LINES; l++ )
		{
			m_sprBullets[l].SetName( ssprintf("Bullet%d",l+1) );
			m_sprBullets[l].Load( THEME->GetPathToG( ssprintf("ScreenRanking bullets 1x%d",NUM_RANKING_LINES) ) );
			m_sprBullets[l].SetState( l );
			m_sprBullets[l].StopAnimating();
			m_sprBullets[l].SetHidden( true );
			this->AddChild( &m_sprBullets[l] );

			m_textNames[l].SetName( ssprintf("Name%d",l+1) );
			m_textNames[l].LoadFromFont( THEME->GetPathToF("ScreenRanking name") );
			m_textNames[l].SetHidden( true );
			this->AddChild( &m_textNames[l] );

			m_textScores[l].SetName( ssprintf("Score%d",l+1) );
			m_textScores[l].LoadFromFont( THEME->GetPathToF("ScreenRanking score") );
			m_textScores[l].SetHidden( true );
			this->AddChild( &m_textScores[l] );

			m_textPoints[l].SetName( ssprintf("Points%d",l+1) );
			m_textPoints[l].LoadFromFont( THEME->GetPathToF("ScreenRanking points") );
			m_textPoints[l].SetHidden( true );
			this->AddChild( &m_textPoints[l] );
			
			m_textTime[l].SetName( ssprintf("Time%d",l+1) );
			m_textTime[l].LoadFromFont( THEME->GetPathToF("ScreenRanking time") );
			m_textTime[l].SetHidden( true );
			this->AddChild( &m_textTime[l] );

			// TODO: Think of a better way to handle this
			if( PREFSMAN->m_sCoursesToShowRanking == "" )
				PREFSMAN->m_sCoursesToShowRanking = THEME->GetMetric("ScreenRanking","CoursesToShow");
		}
	}

	// make the list of difficulties to show
	{
		vector<CString> sShowDiffs;
		split( DIFFICULTIES_TO_SHOW, ",", sShowDiffs, true );

		for( vector<CString>::const_iterator iter = sShowDiffs.begin(); iter != sShowDiffs.end(); iter++ )
		{
			m_vDiffsToShow.push_back( StringToDifficulty( *iter ) );
		}
	}

	// init Actors for all_steps
	{
		FOREACH_Difficulty( d )
		{
			bool bShowThis = find(m_vDiffsToShow.begin(), m_vDiffsToShow.end(), d) != m_vDiffsToShow.end();
			if( !bShowThis )
				continue;	// skip

			m_sprDifficulty[d].Load( THEME->GetPathG(m_sName,"difficulty "+DifficultyToString(d)) );
			m_sprDifficulty[d]->SetName( ssprintf("Difficulty%d",d) );
			m_sprDifficulty[d]->SetHidden( true );
			this->AddChild( m_sprDifficulty[d] );
		}
		const unsigned num_songs = SONGMAN->GetAllSongs().size();
		for( unsigned s=0; s<num_songs; s++ )
		{
			Song *pSong = SONGMAN->GetAllSongs()[s];
			if( UNLOCKMAN->SongIsLocked(pSong) )
				continue;
			if( !pSong->ShowInDemonstrationAndRanking() )
				continue;

			StepsScoreRowItem* pStepsScoreRowItem = new StepsScoreRowItem;
			pStepsScoreRowItem ->m_pSong = pSong;

			pStepsScoreRowItem->m_sprSongFrame.SetName( "SongFrame" );
			pStepsScoreRowItem->m_sprSongFrame.SetHidden( true );
			pStepsScoreRowItem->m_sprSongFrame.Load( THEME->GetPathToG("ScreenRanking song frame") );
			pStepsScoreRowItem->AddChild( &pStepsScoreRowItem->m_sprSongFrame );

			pStepsScoreRowItem->m_textSongTitle.SetName( "SongTitle" );
			pStepsScoreRowItem->m_textSongTitle.SetHidden( true );
			pStepsScoreRowItem->m_textSongTitle.LoadFromFont( THEME->GetPathToF("ScreenRanking song title") );
			pStepsScoreRowItem->AddChild( &pStepsScoreRowItem->m_textSongTitle );

			for( int d=0; d<NUM_DIFFICULTIES; d++ )
			{
				pStepsScoreRowItem->m_textStepsScore[d].SetName( "StepsScore" );
				pStepsScoreRowItem->m_textStepsScore[d].LoadFromFont( THEME->GetPathToF("ScreenRanking steps score") );
				pStepsScoreRowItem->m_textStepsScore[d].SetHidden( true );
				pStepsScoreRowItem->AddChild( &pStepsScoreRowItem->m_textStepsScore[d] );
			}

			m_vpStepsScoreRowItem.push_back( pStepsScoreRowItem );
		}

		m_ListScoreRowItems.SetName( "ListScoreRowItems" );
		this->AddChild( &m_ListScoreRowItems );
		m_ListScoreRowItems.SetXY( CENTER_X, CENTER_Y );
	}

	{
		// for all_courses:
		FOREACH_ShownCourseDifficulty(d)
		{
			CString cd = CourseDifficultyToString(d);
			m_sprCourseDifficulty[d].Load( THEME->GetPathG(m_sName,"CourseDifficulty "+cd) );
			m_sprCourseDifficulty[d]->SetName( ssprintf("CourseDifficulty%s",cd.c_str()) );
			m_sprCourseDifficulty[d]->SetHidden( true );
			this->AddChild( m_sprCourseDifficulty[d] );
		}

		vector<Course*> courses;
		SONGMAN->GetAllCourses( courses, false );
		LOG->Trace("rankings: adding %u courses", unsigned(courses.size()));
		for( unsigned s=0; s<courses.size(); s++ )
		{
			if( UNLOCKMAN->CourseIsLocked(courses[s]) )
				continue;

			CourseScoreRowItem* pCourseScoreRowItem = new CourseScoreRowItem;
			pCourseScoreRowItem->m_pCourse = courses[s];

			pCourseScoreRowItem->m_sprSongFrame.SetName( "CourseListFrame" );
			pCourseScoreRowItem->m_sprSongFrame.SetHidden( true );
			pCourseScoreRowItem->m_sprSongFrame.Load( THEME->GetPathToG("ScreenRanking course frame") );
			pCourseScoreRowItem->AddChild( &pCourseScoreRowItem->m_sprSongFrame );

			pCourseScoreRowItem->m_textSongTitle.SetName( "CourseListTitle" );
			pCourseScoreRowItem->m_textSongTitle.SetHidden( true );
			pCourseScoreRowItem->m_textSongTitle.LoadFromFont( THEME->GetPathToF("ScreenRanking course list title") );
			pCourseScoreRowItem->AddChild( &pCourseScoreRowItem->m_textSongTitle );

			FOREACH_ShownCourseDifficulty(d)
			{
				pCourseScoreRowItem->m_textStepsScore[d].SetName( "CourseListScore" );
				pCourseScoreRowItem->m_textStepsScore[d].LoadFromFont( THEME->GetPathToF("ScreenRanking course list score") );
				pCourseScoreRowItem->m_textStepsScore[d].SetHidden( true );
				pCourseScoreRowItem->AddChild( &pCourseScoreRowItem->m_textStepsScore[d] );
			}

			m_vpCourseScoreRowItem.push_back( pCourseScoreRowItem );
		}

		m_ListCourseRowItems.SetName( "ListCourseRowItems" );
		this->AddChild( &m_ListCourseRowItems );
		m_ListCourseRowItems.SetXY( CENTER_X, CENTER_Y );
	}

	// calculate which StepsTypes to show
	vector<StepsType> aStepsTypesToShow;
	{
		GAMEMAN->GetStepsTypesForGame( GAMESTATE->m_pCurGame, aStepsTypesToShow );

		// subtract hidden StepsTypes
		{
			vector<CString> asStepsTypesToHide;
			split( STEPS_TYPES_TO_HIDE, ",", asStepsTypesToHide, true );
			for( unsigned i=0; i<asStepsTypesToHide.size(); i++ )
			{
				StepsType st = GameManager::StringToStepsType(asStepsTypesToHide[i]);
				if( st != STEPS_TYPE_INVALID )
				{
					const vector<StepsType>::iterator iter = find( aStepsTypesToShow.begin(), aStepsTypesToShow.end(), st );
					if( iter != aStepsTypesToShow.end() )
						aStepsTypesToShow.erase( iter );
				}
			}
		}
	}

	//
	// fill m_vPagesToShow
	//
	if( SHOW_CATEGORIES )
	{
		for( unsigned i=0; i<aStepsTypesToShow.size(); i++ )
		{
			for( int c=0; c<NUM_RANKING_CATEGORIES; c++ )
			{
				PageToShow pts;
				pts.type = PAGE_TYPE_CATEGORY;
				pts.colorIndex = i;
				pts.category = (RankingCategory)c;
				pts.nt = aStepsTypesToShow[i];
				m_vPagesToShow.push_back( pts );
			}
		}
	}

	{
		vector<CString> asCoursePaths;
		split( COURSES_TO_SHOW, ",", asCoursePaths, true );
		for( unsigned i=0; i<aStepsTypesToShow.size(); i++ )
		{
			for( unsigned c=0; c<asCoursePaths.size(); c++ )
			{
				PageToShow pts;
				pts.type = PAGE_TYPE_TRAIL;
				pts.colorIndex = i;
				pts.nt = aStepsTypesToShow[i];
				pts.pCourse = SONGMAN->GetCourseFromPath( asCoursePaths[c] );
				if( pts.pCourse == NULL )
					continue;

				pts.pTrail = pts.pCourse->GetTrail( pts.nt );
				if( pts.pTrail == NULL )
					continue;

				m_vPagesToShow.push_back( pts );
			}
		}
	}

	if( SHOW_ALL_STEPS_SCORES )
	{
		vector<Song*> vpSongs = SONGMAN->GetAllSongs();
		if( !vpSongs.empty() )
		{
			for( unsigned i=0; i<aStepsTypesToShow.size(); i++ )
			{
				PageToShow pts;
				pts.type = PAGE_TYPE_ALL_STEPS;
				pts.colorIndex = i;
				pts.nt = aStepsTypesToShow[i];
				m_vPagesToShow.push_back( pts );
			}
		}
	}

	if( SHOW_ALL_COURSE_SCORES )
	{
		vector<Course*> courses;
		SONGMAN->GetAllCourses( courses, false );
		if( !courses.empty() )
		{
			for( unsigned i=0; i<aStepsTypesToShow.size(); i++ )
			{
				PageToShow pts;
				pts.type = PAGE_TYPE_ALL_COURSES;
				pts.colorIndex = i;
				pts.nt = aStepsTypesToShow[i];
				m_vPagesToShow.push_back( pts );
			}
		}
	}

	this->ClearMessageQueue( SM_BeginFadingOut );	// ignore ScreenAttract's SecsToShow

	this->PostScreenMessage( SM_ShowNextPage, 0.5f );
}
bool CourseWriterCRS::Write( const Course &course, RageFileBasic &f, bool bSavingCache )
{
	ASSERT( !course.m_bIsAutogen );

	f.PutLine( ssprintf("#COURSE:%s;", course.m_sMainTitle.c_str()) );
	if( course.m_sMainTitleTranslit != "" )
		f.PutLine( ssprintf("#COURSETRANSLIT:%s;", course.m_sMainTitleTranslit.c_str()) );
	if( course.m_sScripter != "" )
		f.PutLine( ssprintf("#SCRIPTER:%s;", course.m_sScripter.c_str()) );
	if( course.m_bRepeat )
		f.PutLine( "#REPEAT:YES;" );
	if( course.m_iLives != -1 )
		f.PutLine( ssprintf("#LIVES:%i;", course.m_iLives) );
	if( !course.m_sBannerPath.empty() )
		f.PutLine( ssprintf("#BANNER:%s;", course.m_sBannerPath.c_str()) );

	if( !course.m_setStyles.empty() )
	{
		vector<RString> asStyles;
		asStyles.insert( asStyles.begin(), course.m_setStyles.begin(), course.m_setStyles.end() );
		f.PutLine( ssprintf("#STYLE:%s;", join( ",", asStyles ).c_str()) );
	}

	FOREACH_ENUM( CourseDifficulty,cd )
	{
		if( course.m_iCustomMeter[cd] == -1 )
			continue;
		f.PutLine( ssprintf("#METER:%s:%i;", DifficultyToCRSString(cd).c_str(), course.m_iCustomMeter[cd]) );
	}

	if( bSavingCache )
	{
		f.PutLine( "// cache tags:" );

		Course::RadarCache_t::const_iterator it;
		for( it = course.m_RadarCache.begin(); it != course.m_RadarCache.end(); ++it )
		{
			// #RADAR:type:difficulty:value,value,value...;
			const Course::CacheEntry &entry = it->first;
			StepsType st = entry.first;
			CourseDifficulty cd = entry.second;

			vector<RString> asRadarValues;
			const RadarValues &rv = it->second;
			for( int r=0; r < NUM_RadarCategory; r++ )
				asRadarValues.push_back( ssprintf("%.3f", rv[r]) );
			RString sLine = ssprintf( "#RADAR:%i:%i:", st, cd );
			sLine += join( ",", asRadarValues ) + ";";
			f.PutLine( sLine );
		}
		f.PutLine( "// end cache tags" );
	}

	for( unsigned i=0; i<course.m_vEntries.size(); i++ )
	{
		const CourseEntry& entry = course.m_vEntries[i];

		for( unsigned j = 0; j < entry.attacks.size(); ++j )
		{
			if( j == 0 )
				f.PutLine( "#MODS:" );

			const Attack &a = entry.attacks[j];
			f.Write( ssprintf( "  TIME=%.2f:LEN=%.2f:MODS=%s",
				a.fStartSecond, a.fSecsRemaining, a.sModifiers.c_str() ) );

			if( j+1 < entry.attacks.size() )
				f.Write( ":" );
			else
				f.Write( ";" );
			f.PutLine( "" );
		}

		if( entry.fGainSeconds > 0 )
			f.PutLine( ssprintf("#GAINSECONDS:%f;", entry.fGainSeconds) );

		if( entry.songSort == SongSort_MostPlays  &&  entry.iChooseIndex != -1 )
		{
			f.Write( ssprintf( "#SONG:BEST%d", entry.iChooseIndex+1 ) );
		}
		else if( entry.songSort == SongSort_FewestPlays  &&  entry.iChooseIndex != -1 )
		{
			f.Write( ssprintf( "#SONG:WORST%d", entry.iChooseIndex+1 ) );
		}
		else if( entry.songID.ToSong() )
		{
			Song *pSong = entry.songID.ToSong();
			const RString &sSong = Basename( pSong->GetSongDir() );
			
			f.Write( "#SONG:" );
			if( !entry.songCriteria.m_sGroupName.empty() )
				f.Write( entry.songCriteria.m_sGroupName + '/' );
			f.Write( sSong );
		}
		else if( !entry.songCriteria.m_sGroupName.empty() )
		{
			f.Write( ssprintf( "#SONG:%s/*", entry.songCriteria.m_sGroupName.c_str() ) );
		}
		else
		{
			f.Write( "#SONG:*" );
		}

		f.Write( ":" );
		if( entry.stepsCriteria.m_difficulty != Difficulty_Invalid )
			f.Write( DifficultyToString(entry.stepsCriteria.m_difficulty) );
		else if( entry.stepsCriteria.m_iLowMeter != -1  &&  entry.stepsCriteria.m_iHighMeter != -1 )
			f.Write( ssprintf( "%d..%d", entry.stepsCriteria.m_iLowMeter, entry.stepsCriteria.m_iHighMeter ) );
		f.Write( ":" );

		RString sModifiers = entry.sModifiers;

		if( entry.bSecret )
		{
			if( sModifiers != "" )
				sModifiers += ",";
			sModifiers += entry.bSecret? "noshowcourse":"showcourse";
		}

		if( entry.bNoDifficult )
		{
			if( sModifiers != "" )
				sModifiers += ",";
			sModifiers += "nodifficult";
		}

		if( entry.iGainLives > -1 )
		{
			if( !sModifiers.empty() )
				sModifiers += ',';
			sModifiers += ssprintf( "award%d", entry.iGainLives );
		}
		
		f.Write( sModifiers );

		f.PutLine( ";" );
	}	
	
	return true;
}
void EditCoursesSongMenu::OnRowValueChanged( Row row )
{
	LOG->Trace( "EditCoursesSongMenu::OnRowValueChanged(%i)", row );

	m_sprArrows[0].SetDiffuse( CanGoLeft()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) );
	m_sprArrows[1].SetDiffuse( CanGoRight()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) );
	m_sprArrows[0].EnableAnimation( CanGoLeft() );
	m_sprArrows[1].EnableAnimation( CanGoRight() );

	CString sGroup = GetSelectedGroup();
	Song *pSong = GetSelectedSong();
	
	switch( row )
	{
	case ROW_GROUP:
	{
		CHECKPOINT;
		m_textValue[ROW_GROUP].SetText( sGroup );

		UpdateSongList();

		pSong = GetSelectedSong();
	}
		// fall through
	case ROW_SONG:
		CHECKPOINT;
		m_textValue[ROW_SONG].SetText( pSong? pSong->GetTranslitMainTitle():CString("") );
		// fall through

	case ROW_TYPE:
		CHECKPOINT;
		m_textValue[ROW_TYPE].SetText( CourseEntryTypeToString(GetSelectedType()) );
		for( int i = 0; i < NUM_ROWS; ++i )
			m_textValue[i].SetDiffuse( 
				g_bRowEnabledForType[GetSelectedType()][i]?
					RageColor(1,1,1,1):RageColor(0.4f,0.4f,0.4f,1) );
		// fall through

	case ROW_DIFFICULTY:
	{
		CHECKPOINT;
		Difficulty dc = GetSelectedDifficulty();
		if( dc == DIFFICULTY_INVALID )
			m_textValue[ROW_DIFFICULTY].SetText( "(any)" );
		else
			m_textValue[ROW_DIFFICULTY].SetText( DifficultyToString(dc) );
		// fall through
	}
	case ROW_LOW_METER:
		CHECKPOINT;
		if( GetLowMeter() == -1 )
			m_textValue[ROW_LOW_METER].SetText( "(any)" );
		else
			m_textValue[ROW_LOW_METER].SetText( ssprintf("%d",GetLowMeter()) );
		// fall through

	case ROW_HIGH_METER:
		CHECKPOINT;
		if( GetHighMeter() == -1 )
			m_textValue[ROW_HIGH_METER].SetText( "(any)" );
		else
			m_textValue[ROW_HIGH_METER].SetText( ssprintf("%d",GetHighMeter()) );
		// fall through

	case ROW_BEST_WORST_VALUE:
		CHECKPOINT;
		m_textValue[ROW_BEST_WORST_VALUE].SetText( ssprintf("%d",GetBestWorst()+1) );
		break;

	default:
		ASSERT(0);	// invalid row
	}
}
RString TrailID::ToString() const
{
	RString s = GAMEMAN->GetStepsTypeInfo(st).szName;
	s += " " + DifficultyToString( cd );
	return s;
}
Beispiel #7
0
void EditCoursesMenu::OnRowValueChanged( Row row )
{
	LOG->Trace( "EditCoursesMenu::OnRowValueChanged(%i)", row );

	const bool bCanGoLeft = CanGoLeft(), bCanGoRight = CanGoRight();
	m_sprArrows[0].SetDiffuse( bCanGoLeft?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) );
	m_sprArrows[1].SetDiffuse( bCanGoRight?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) );
	m_sprArrows[0].EnableAnimation( bCanGoLeft );
	m_sprArrows[1].EnableAnimation( bCanGoRight );

	Course* pCourse = GetSelectedCourse();
	CourseEntry* pEntry = GetSelectedEntry();

	switch( row )
	{
	case ROW_COURSE:
		CHECKPOINT;
		m_textValue[ROW_COURSE].SetText( pCourse->GetFullDisplayTitle() );
		m_CourseBanner.LoadFromCourse( pCourse );
		m_CourseBanner.ScaleToClipped( COURSE_BANNER_WIDTH, COURSE_BANNER_HEIGHT );
		m_iSelection[ROW_ENTRY] = 0;
		pEntry = GetSelectedEntry();
		if( pEntry == NULL )
		{
			CourseEntry ce;
			const vector<Song*> &apSongs = SONGMAN->GetAllSongs();
			ASSERT( !apSongs.empty() );
			ce.pSong = apSongs[0];
			pCourse->m_entries.push_back( ce );
			pEntry = GetSelectedEntry();
		}
		// fall through
	case ROW_COURSE_OPTIONS:
		CHECKPOINT;
		m_textValue[ROW_COURSE_OPTIONS].SetText( 
			ssprintf(
				"(START)  %s, %s, ",
				pCourse->m_bRepeat ? "repeat" : "no repeat",
				pCourse->m_bRandomize ? "randomize" : "no randomize" ) + 
			ssprintf(
				(pCourse->m_iLives==-1) ? "use bar life" : "%d lives",
				pCourse->m_iLives ) );
		// fall through
	case ROW_ACTION:
		CHECKPOINT;
		m_textValue[ROW_ACTION].SetText( "(START) " + ActionToString(GetSelectedAction()) );
		// fall through
	case ROW_ENTRY:
		CHECKPOINT;
		m_textValue[ROW_ENTRY].SetText( ssprintf("%d of %d",m_iSelection[ROW_ENTRY]+1, (int)GetSelectedCourse()->m_entries.size()) );
		m_iSelection[ROW_ENTRY_TYPE] = pEntry->type;
		// fall through
	case ROW_ENTRY_TYPE:
		CHECKPOINT;
		m_textValue[ROW_ENTRY_TYPE].SetText( pEntry ? CourseEntryTypeToString(pEntry->type) : CString("(none)") );
		// fall through
	case ROW_ENTRY_OPTIONS:
		CHECKPOINT;
		{
			CStringArray as;
			const bool *bShow = g_bRowEnabledForType[GetSelectedEntry()->type];

			if( bShow[song] )
				as.push_back( pEntry->pSong ? pEntry->pSong->GetFullTranslitTitle() : CString("(missing song)") );
			if( bShow[group] )
				as.push_back( pEntry->group_name.empty() ? CString("(no group)") : pEntry->group_name );
			if( bShow[difficulty] )
				if( pEntry->difficulty != DIFFICULTY_INVALID )
					as.push_back( DifficultyToString(pEntry->difficulty) );
			if( bShow[low_meter] )
				if( pEntry->low_meter > 0 )
					as.push_back( ssprintf("low meter %d", pEntry->low_meter) );
			if( bShow[high_meter] )
				if( pEntry->high_meter > 0 )
					as.push_back( ssprintf("high meter %d", pEntry->high_meter) );
			if( bShow[best_worst_value] )
				if( pEntry->players_index != -1 )
					as.push_back( ssprintf("rank %d", pEntry->players_index+1) );

			m_textValue[ROW_ENTRY_OPTIONS].SetText( "(START) " + join(", ",as) );
		}
		// fall through
	case ROW_ENTRY_PLAYER_OPTIONS:
		CHECKPOINT;
		{
			CString s = "(START) ";
		
			PlayerOptions po;
			po.FromString( pEntry->modifiers );
			if( po.GetString().empty() )
				s += "(none)";
			else
				s += po.GetString();
		
			m_textValue[ROW_ENTRY_PLAYER_OPTIONS].SetText( s );
		}
		// fall through
	case ROW_ENTRY_SONG_OPTIONS:
		CHECKPOINT;
		{
			CString s = "(START) ";

			SongOptions so;
			so.FromString( pEntry->modifiers );
			if( so.GetString().empty() )
				s += "(none)";
			else
				s += so.GetString();

			m_textValue[ROW_ENTRY_SONG_OPTIONS].SetText( s );
		}
		break;
	default:
		ASSERT(0);	// invalid row
	}
}
Beispiel #8
0
XNode* Profile::SaveGeneralDataCreateNode() const
{
	XNode* pGeneralDataNode = new XNode;
	pGeneralDataNode->name = "GeneralData";

	// TRICKY: These are write-only elements that are never read again.  This 
	// data is required by other apps (like internet ranking), but is 
	// redundant to the game app.
	pGeneralDataNode->AppendChild( "DisplayName",					GetDisplayName() );
	pGeneralDataNode->AppendChild( "IsMachine",						IsMachine() );

	pGeneralDataNode->AppendChild( "Guid",							m_sGuid );
	pGeneralDataNode->AppendChild( "UsingProfileDefaultModifiers",	m_bUsingProfileDefaultModifiers );
	pGeneralDataNode->AppendChild( "DefaultModifiers",				m_sDefaultModifiers );
	pGeneralDataNode->AppendChild( "SortOrder",						SortOrderToString(m_SortOrder) );
	pGeneralDataNode->AppendChild( "LastDifficulty",				DifficultyToString(m_LastDifficulty) );
	pGeneralDataNode->AppendChild( "LastCourseDifficulty",			CourseDifficultyToString(m_LastCourseDifficulty) );
	pGeneralDataNode->AppendChild( m_lastSong.CreateNode() );
	pGeneralDataNode->AppendChild( m_lastCourse.CreateNode() );
	pGeneralDataNode->AppendChild( "TotalPlays",					m_iTotalPlays );
	pGeneralDataNode->AppendChild( "TotalPlaySeconds",				m_iTotalPlaySeconds );
	pGeneralDataNode->AppendChild( "TotalGameplaySeconds",			m_iTotalGameplaySeconds );
	pGeneralDataNode->AppendChild( "CurrentCombo",					m_iCurrentCombo );
	pGeneralDataNode->AppendChild( "TotalCaloriesBurned",			m_fTotalCaloriesBurned );
	pGeneralDataNode->AppendChild( "LastPlayedMachineGuid",			m_sLastPlayedMachineGuid );
	pGeneralDataNode->AppendChild( "LastPlayedDate",				m_LastPlayedDate );
	pGeneralDataNode->AppendChild( "TotalDancePoints",				m_iTotalDancePoints );
	pGeneralDataNode->AppendChild( "NumExtraStagesPassed",			m_iNumExtraStagesPassed );
	pGeneralDataNode->AppendChild( "NumExtraStagesFailed",			m_iNumExtraStagesFailed );
	pGeneralDataNode->AppendChild( "NumToasties",					m_iNumToasties );
	pGeneralDataNode->AppendChild( "TotalTapsAndHolds",				m_iTotalTapsAndHolds );
	pGeneralDataNode->AppendChild( "TotalJumps",					m_iTotalJumps );
	pGeneralDataNode->AppendChild( "TotalHolds",					m_iTotalHolds );
	pGeneralDataNode->AppendChild( "TotalMines",					m_iTotalMines );
	pGeneralDataNode->AppendChild( "TotalHands",					m_iTotalHands );

	// Keep declared variables in a very local scope so they aren't 
	// accidentally used where they're not intended.  There's a lot of
	// copying and pasting in this code.

	{
		XNode* pUnlockedSongs = pGeneralDataNode->AppendChild("UnlockedSongs");
		for( set<int>::const_iterator it = m_UnlockedSongs.begin(); it != m_UnlockedSongs.end(); ++it )
			pUnlockedSongs->AppendChild( ssprintf("Unlock%i", *it) );
	}

	{
		XNode* pNumSongsPlayedByPlayMode = pGeneralDataNode->AppendChild("NumSongsPlayedByPlayMode");
		FOREACH_PlayMode( pm )
		{
			/* Don't save unplayed PlayModes. */
			if( !m_iNumSongsPlayedByPlayMode[pm] )
				continue;
			pNumSongsPlayedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumSongsPlayedByPlayMode[pm] );
		}
	}

	{
		XNode* pNumSongsPlayedByStyle = pGeneralDataNode->AppendChild("NumSongsPlayedByStyle");
		for( map<StyleID,int>::const_iterator iter = m_iNumSongsPlayedByStyle.begin();
			iter != m_iNumSongsPlayedByStyle.end();
			iter++ )
		{
			const StyleID &s = iter->first;
			int iNumPlays = iter->second;

			XNode *pStyleNode = s.CreateNode();
			pStyleNode->SetValue( iNumPlays );

			pNumSongsPlayedByStyle->AppendChild( pStyleNode );
		}
	}

	{
		XNode* pNumSongsPlayedByDifficulty = pGeneralDataNode->AppendChild("NumSongsPlayedByDifficulty");
		FOREACH_Difficulty( dc )
		{
			if( !m_iNumSongsPlayedByDifficulty[dc] )
				continue;
			pNumSongsPlayedByDifficulty->AppendChild( DifficultyToString(dc), m_iNumSongsPlayedByDifficulty[dc] );
		}
	}

	{
		XNode* pNumSongsPlayedByMeter = pGeneralDataNode->AppendChild("NumSongsPlayedByMeter");
		for( int i=0; i<MAX_METER+1; i++ )
		{
			if( !m_iNumSongsPlayedByMeter[i] )
				continue;
			pNumSongsPlayedByMeter->AppendChild( ssprintf("Meter%d",i), m_iNumSongsPlayedByMeter[i] );
		}
	}

	{
		XNode* pNumStagesPassedByGrade = pGeneralDataNode->AppendChild("NumStagesPassedByGrade");
		FOREACH_Grade( g )
		{
			if( !m_iNumStagesPassedByGrade[g] )
				continue;
			pNumStagesPassedByGrade->AppendChild( GradeToString(g), m_iNumStagesPassedByGrade[g] );
		}
	}

	{
		XNode* pNumStagesPassedByPlayMode = pGeneralDataNode->AppendChild("NumStagesPassedByPlayMode");
		FOREACH_PlayMode( pm )
		{
			/* Don't save unplayed PlayModes. */
			if( !m_iNumStagesPassedByPlayMode[pm] )
				continue;
			pNumStagesPassedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumStagesPassedByPlayMode[pm] );
		}
	}

	return pGeneralDataNode;
}
Beispiel #9
0
static NoteData ParseNoteData(RString &step1, RString &step2,
			      Steps &out, const RString &path)
{
	g_mapDanceNoteToNoteDataColumn.clear();
	switch( out.m_StepsType )
	{
		case StepsType_dance_single:
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
			break;
		case StepsType_dance_double:
		case StepsType_dance_couple:
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7;
			break;
		case StepsType_dance_solo:
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPLEFT] = 1;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 2;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 3;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPRIGHT] = 4;
			g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 5;
			break;
			DEFAULT_FAIL( out.m_StepsType );
	}
	
	NoteData newNoteData;
	newNoteData.SetNumTracks( g_mapDanceNoteToNoteDataColumn.size() );
	
	for( int pad=0; pad<2; pad++ )		// foreach pad
	{
		RString sStepData;
		switch( pad )
		{
			case 0:
				sStepData = step1;
				break;
			case 1:
				if( step2 == "" )	// no data
					continue;	// skip
				sStepData = step2;
				break;
				DEFAULT_FAIL( pad );
		}
		
		sStepData.Replace("\n", "");
		sStepData.Replace("\r", "");
		sStepData.Replace("\t", "");
		sStepData.Replace(" ", "");
		
		double fCurrentBeat = 0;
		double fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
		
		for( size_t i=0; i<sStepData.size(); )
		{
			char c = sStepData[i++];
			switch( c )
			{
					// begins a series
				case '(':
					fCurrentIncrementer = 1.0/16 * BEATS_PER_MEASURE;
					break;
				case '[':
					fCurrentIncrementer = 1.0/24 * BEATS_PER_MEASURE;
					break;
				case '{':
					fCurrentIncrementer = 1.0/64 * BEATS_PER_MEASURE;
					break;
				case '`':
					fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
					break;
					
					// ends a series
				case ')':
				case ']':
				case '}':
				case '\'':
				case '>':
					fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
					break;
					
				default:	// this is a note character
				{
					if( c == '!' )
					{
						LOG->UserLog(
							     "Song file",
							     path,
							     "has an unexpected character: '!'." );
						continue;
					}
					
					bool jump = false;
					if( c == '<' )
					{
						/* Arr.  Is this a jump or a 1/192 marker? */
						if( Is192( sStepData, i ) )
						{
							fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
							break;
						}
						
						/* It's a jump.
						 * We need to keep reading notes until we hit a >. */
						jump = true;
						i++;
					}
					
					const int iIndex = BeatToNoteRow( (float)fCurrentBeat );
					i--;
					do {
						c = sStepData[i++];
						
						if( jump && c == '>' )
							break;
						
						int iCol1, iCol2;
						DWIcharToNoteCol(
								 c,
								 (GameController)pad,
								 iCol1,
								 iCol2,
								 path );
						
						if( iCol1 != -1 )
							newNoteData.SetTapNote(iCol1,
									       iIndex,
									       TAP_ORIGINAL_TAP);
						if( iCol2 != -1 )
							newNoteData.SetTapNote(iCol2,
									       iIndex,
									       TAP_ORIGINAL_TAP);
						
						if(i>=sStepData.length())
						{
							break;
							//we ran out of data
							//while looking for the ending > mark
						}
						
						if( sStepData[i] == '!' )
						{
							i++;
							const char holdChar = sStepData[i++];
							
							DWIcharToNoteCol(holdChar,
									 (GameController)pad,
									 iCol1,
									 iCol2,
									 path );
							
							if( iCol1 != -1 )
								newNoteData.SetTapNote(iCol1,
										       iIndex,
										       TAP_ORIGINAL_HOLD_HEAD);
							if( iCol2 != -1 )
								newNoteData.SetTapNote(iCol2,
										       iIndex,
										       TAP_ORIGINAL_HOLD_HEAD);
						}
					}
					while( jump );
					fCurrentBeat += fCurrentIncrementer;
				}
					break;
			}
		}
	}
	
	/* Fill in iDuration. */
	for( int t=0; t<newNoteData.GetNumTracks(); ++t )
	{
		FOREACH_NONEMPTY_ROW_IN_TRACK( newNoteData, t, iHeadRow )
		{
			TapNote tn = newNoteData.GetTapNote( t, iHeadRow  );
			if( tn.type != TapNote::hold_head )
				continue;
			
			int iTailRow = iHeadRow;
			bool bFound = false;
			while( !bFound && newNoteData.GetNextTapNoteRowForTrack(t, iTailRow) )
			{
				const TapNote &TailTap = newNoteData.GetTapNote( t, iTailRow );
				if( TailTap.type == TapNote::empty )
					continue;
				
				newNoteData.SetTapNote( t, iTailRow, TAP_EMPTY );
				tn.iDuration = iTailRow - iHeadRow;
				newNoteData.SetTapNote( t, iHeadRow, tn );
				bFound = true;
			}
			
			if( !bFound )
			{
				/* The hold was never closed.  */
				LOG->UserLog("Song file",
					     path,
					     "failed to close a hold note in \"%s\" on track %i", 
					     DifficultyToString(out.GetDifficulty()).c_str(),
					     t);
				
				newNoteData.SetTapNote( t, iHeadRow, TAP_EMPTY );
			}
		}
	}
Beispiel #10
0
void EditMenu::OnRowValueChanged( Row row )
{
	m_sprArrows[0].SetDiffuse( CanGoLeft()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) );
	m_sprArrows[1].SetDiffuse( CanGoRight()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) );
	m_sprArrows[0].EnableAnimation( CanGoLeft() );
	m_sprArrows[1].EnableAnimation( CanGoRight() );

	switch( row )
	{
	case ROW_GROUP:
		m_textValue[ROW_GROUP].SetText( SONGMAN->ShortenGroupName(GetSelectedGroup()) );
		m_GroupBanner.LoadFromGroup( GetSelectedGroup() );
		m_GroupBanner.ScaleToClipped( GROUP_BANNER_WIDTH, GROUP_BANNER_HEIGHT );
		m_pSongs.clear();
		SONGMAN->GetSongs( m_pSongs, GetSelectedGroup() );
		m_iSelection[ROW_SONG] = 0;
		// fall through
	case ROW_SONG:
		m_textValue[ROW_SONG].SetText( "" );
		m_SongBanner.LoadFromSong( GetSelectedSong() );
		m_SongBanner.ScaleToClipped( SONG_BANNER_WIDTH, SONG_BANNER_HEIGHT );
		m_SongTextBanner.LoadFromSong( GetSelectedSong() );
		// fall through
	case ROW_STEPS_TYPE:
		m_textValue[ROW_STEPS_TYPE].SetText( GAMEMAN->StepsTypeToString(GetSelectedStepsType()) );
		// fall through
	case ROW_DIFFICULTY:
		m_textValue[ROW_DIFFICULTY].SetText( DifficultyToString(GetSelectedDifficulty()) );
		m_Meter.SetFromSteps( GetSelectedNotes() );
		// fall through
	case ROW_SOURCE_STEPS_TYPE:
		m_textLabel[ROW_SOURCE_STEPS_TYPE].SetDiffuse( GetSelectedNotes()?RageColor(1,1,1,0):RageColor(1,1,1,1) );
		m_textValue[ROW_SOURCE_STEPS_TYPE].SetDiffuse( GetSelectedNotes()?RageColor(1,1,1,0):RageColor(1,1,1,1) );
		m_textValue[ROW_SOURCE_STEPS_TYPE].SetText( GAMEMAN->StepsTypeToString(GetSelectedSourceStepsType()) );
		// fall through
	case ROW_SOURCE_DIFFICULTY:
		m_textLabel[ROW_SOURCE_DIFFICULTY].SetDiffuse( GetSelectedNotes()?RageColor(1,1,1,0):RageColor(1,1,1,1) );
		m_textValue[ROW_SOURCE_DIFFICULTY].SetDiffuse( GetSelectedNotes()?RageColor(1,1,1,0):RageColor(1,1,1,1) );
		m_textValue[ROW_SOURCE_DIFFICULTY].SetText( DifficultyToString(GetSelectedSourceDifficulty()) );
		m_SourceMeter.SetFromSteps( GetSelectedSourceNotes() );
		m_SourceMeter.SetZoomY( GetSelectedNotes()?0.f:1.f );

		m_Actions.clear();
		if( GetSelectedNotes() )
		{
			m_Actions.push_back( ACTION_EDIT );
			m_Actions.push_back( ACTION_DELETE );
		}
		else if( GetSelectedSourceNotes() )
		{
			m_Actions.push_back( ACTION_COPY );
			m_Actions.push_back( ACTION_AUTOGEN );
			m_Actions.push_back( ACTION_BLANK );
		}
		else
		{
			m_Actions.push_back( ACTION_BLANK );
		}
		m_iSelection[ROW_ACTION] = 0;
		// fall through
	case ROW_ACTION:
		m_textValue[ROW_ACTION].SetText( ActionToString(GetSelectedAction()) );
		break;
	default:
		ASSERT(0);	// invalid row
	}
}
Beispiel #11
0
static CString GetDifficultyCommandName( Difficulty d ) { return "Set"+DifficultyToString(d); }