Beispiel #1
0
bool KSFLoader::LoadNoteDataFromSimfile( const std::string & cachePath, Steps &out )
{
	bool KIUCompliant = false;
	Song dummy;
	if (!LoadGlobalData(cachePath, dummy, KIUCompliant))
		return false;
	Steps *notes = dummy.CreateSteps();
	if (LoadFromKSFFile(cachePath, *notes, dummy, KIUCompliant))
	{
		KIUCompliant = true; // yeah, reusing a variable.
		out.SetNoteData(notes->GetNoteData());
	}
	delete notes;
	return KIUCompliant;
}
void ScoreKeeperNormal::Load(
		const vector<Song*>& apSongs,
		const vector<Steps*>& apSteps,
		const vector<AttackArray> &asModifiers )
{
	m_apSteps = apSteps;
	ASSERT( apSongs.size() == apSteps.size() );
	ASSERT( apSongs.size() == asModifiers.size() );

	// True if a jump is one to combo, false if combo is purely based on tap count.
	m_ComboIsPerRow.Load( "Gameplay", "ComboIsPerRow" );
	m_MissComboIsPerRow.Load( "Gameplay", "MissComboIsPerRow" );
	m_MinScoreToContinueCombo.Load( "Gameplay", "MinScoreToContinueCombo" );
	m_MinScoreToMaintainCombo.Load( "Gameplay", "MinScoreToMaintainCombo" );
	m_MaxScoreToIncrementMissCombo.Load( "Gameplay", "MaxScoreToIncrementMissCombo" );
	m_MineHitIncrementsMissCombo.Load( "Gameplay", "MineHitIncrementsMissCombo" );
	m_AvoidMineIncrementsCombo.Load( "Gameplay", "AvoidMineIncrementsCombo" );
	m_UseInternalScoring.Load( "Gameplay", "UseInternalScoring" );

	// This can be a function or a number, the type is checked when needed.
	// -Kyz
	m_toasty_trigger.Load("Gameplay", "ToastyTriggersAt");
	m_toasty_min_tns.Load("Gameplay", "ToastyMinTNS");

	// Fill in STATSMAN->m_CurStageStats, calculate multiplier
	int iTotalPossibleDancePoints = 0;
	int iTotalPossibleGradePoints = 0;
	for( unsigned i=0; i<apSteps.size(); i++ )
	{
		Song* pSong = apSongs[i];
		ASSERT( pSong != NULL );
		Steps* pSteps = apSteps[i];
		ASSERT( pSteps != NULL );
		const AttackArray &aa = asModifiers[i];
		NoteData ndTemp;
		pSteps->GetNoteData( ndTemp );

		// We might have been given lots of songs; don't keep them in memory uncompressed.
		pSteps->Compress();

		const Style* pStyle = GAMESTATE->GetCurrentStyle(m_pPlayerState->m_PlayerNumber);
		NoteData ndPre;
		pStyle->GetTransformedNoteDataForStyle( m_pPlayerState->m_PlayerNumber, ndTemp, ndPre );

		/* Compute RadarValues before applying any user-selected mods. Apply
		 * Course mods and count them in the "pre" RadarValues because they're
		 * forced and not chosen by the user. */
		NoteDataUtil::TransformNoteData(ndPre, *(pSteps->GetTimingData()), aa, pSteps->m_StepsType, pSong );

		/* Apply user transforms to find out how the notes will really look.
		 *
		 * XXX: This is brittle: if we end up combining mods for a song differently
		 * than ScreenGameplay, we'll end up with the wrong data.  We should probably
		 * have eg. GAMESTATE->GetOptionsForCourse(po,so,pn) to get options based on
		 * the last call to StoreSelectedOptions and the modifiers list, but that'd
		 * mean moving the queues in ScreenGameplay to GameState ... */
		NoteData ndPost = ndPre;
		NoteDataUtil::TransformNoteData(ndPost, *(pSteps->GetTimingData()), m_pPlayerState->m_PlayerOptions.GetStage(), pSteps->m_StepsType);

		GAMESTATE->SetProcessedTimingData(pSteps->GetTimingData()); // XXX: Not sure why but NoteDataUtil::CalculateRadarValues segfaults without this
		iTotalPossibleDancePoints += this->GetPossibleDancePoints( &ndPre, &ndPost, pSteps->GetTimingData(), pSong->m_fMusicLengthSeconds );
		iTotalPossibleGradePoints += this->GetPossibleGradePoints( &ndPre, &ndPost, pSteps->GetTimingData(), pSong->m_fMusicLengthSeconds );
		GAMESTATE->SetProcessedTimingData(NULL);
	}

	m_pPlayerStageStats->m_iPossibleDancePoints = iTotalPossibleDancePoints;
	m_pPlayerStageStats->m_iPossibleGradePoints = iTotalPossibleGradePoints;

	m_iScoreRemainder = 0;
	m_cur_toasty_combo = 0;
	m_cur_toasty_level= 0;
	// Initialize m_next_toasty_at to 0 so that CalcNextToastyAt just needs to
	// add the value. -Kyz
	m_next_toasty_at= 0;
	m_next_toasty_at= CalcNextToastyAt(m_cur_toasty_level);
	m_iMaxScoreSoFar = 0;
	m_iPointBonus = 0;
	m_iNumTapsAndHolds = 0;
	m_iNumNotesHitThisRow = 0;
	m_bIsLastSongInCourse = false;

	Message msg( "ScoreChanged" );
	msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber );
	msg.SetParam( "MultiPlayer", m_pPlayerState->m_mp );
	MESSAGEMAN->Broadcast( msg );

	memset( m_ComboBonusFactor, 0, sizeof(m_ComboBonusFactor) );
	m_iRoundTo = 1;
}
Beispiel #3
0
static void WriteDWINotesField( RageFile &f, const Steps &out, int start )
{
	NoteData notedata;
	out.GetNoteData( notedata );
	NoteDataUtil::InsertHoldTails( notedata );

	const int iLastMeasure = int( notedata.GetLastBeat()/BEATS_PER_MEASURE );
	for( int m=0; m<=iLastMeasure; m++ )	// foreach measure
	{
		NoteType nt = NoteDataUtil::GetSmallestNoteTypeForMeasure( notedata, m );

		double fCurrentIncrementer = 0;
		switch( nt )
		{
		case NOTE_TYPE_4TH:
		case NOTE_TYPE_8TH:	
			fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
			break;
		case NOTE_TYPE_12TH:
		case NOTE_TYPE_24TH:
			f.Write( "[" );
			fCurrentIncrementer = 1.0/24 * BEATS_PER_MEASURE;
			break;
		case NOTE_TYPE_16TH:
			f.Write( "(" );
			fCurrentIncrementer = 1.0/16 * BEATS_PER_MEASURE;
			break;
		case NOTE_TYPE_32ND:
		case NOTE_TYPE_64TH:
			f.Write( "{" );
			fCurrentIncrementer = 1.0/64 * BEATS_PER_MEASURE;
			break;
		case NOTE_TYPE_48TH:
		case NOTE_TYPE_192ND:
		case NoteType_Invalid:
			// since, for whatever reason, the only way to do
			// 48ths is through a block of 192nds...
			f.Write(  "`" );
			fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
			break;
		default:
			ASSERT_M(0, ssprintf("nt = %d",nt) );
			break;
		}

		double fFirstBeatInMeasure = m * BEATS_PER_MEASURE;
		double fLastBeatInMeasure = (m+1) * BEATS_PER_MEASURE;

		for( double b=fFirstBeatInMeasure; b<=fLastBeatInMeasure-1/64.0f; b+=fCurrentIncrementer )	// need the -0.0001 to account for rounding errors
		{
			int row = BeatToNoteRow( (float)b );

			RString str;
			switch( out.m_StepsType )
			{
			case StepsType_dance_single:
			case StepsType_dance_couple:
			case StepsType_dance_double:
				str = NotesToDWIString( 
					notedata.GetTapNote(start+0, row), 
					notedata.GetTapNote(start+1, row),
					notedata.GetTapNote(start+2, row),
					notedata.GetTapNote(start+3, row) );

				// Blank out the notes so we don't write them again if the incrementer is small
				notedata.SetTapNote(start+0, row, TAP_EMPTY);
				notedata.SetTapNote(start+1, row, TAP_EMPTY);
				notedata.SetTapNote(start+2, row, TAP_EMPTY);
				notedata.SetTapNote(start+3, row, TAP_EMPTY);
				break;
			case StepsType_dance_solo:
				str = NotesToDWIString( 
					notedata.GetTapNote(0, row),
					notedata.GetTapNote(1, row),
					notedata.GetTapNote(2, row),
					notedata.GetTapNote(3, row),
					notedata.GetTapNote(4, row),
					notedata.GetTapNote(5, row) );

				// Blank out the notes so we don't write them again if the incrementer is small
				notedata.SetTapNote(start+0, row, TAP_EMPTY);
				notedata.SetTapNote(start+1, row, TAP_EMPTY);
				notedata.SetTapNote(start+2, row, TAP_EMPTY);
				notedata.SetTapNote(start+3, row, TAP_EMPTY);
				notedata.SetTapNote(start+4, row, TAP_EMPTY);
				notedata.SetTapNote(start+5, row, TAP_EMPTY);
				break;
			default:
				ASSERT(0);	// not a type supported by DWI.  We shouldn't have called in here if that's the case
			}
			f.Write( str );
		}

		switch( nt )
		{
		case NOTE_TYPE_4TH:
		case NOTE_TYPE_8TH:	
			break;
		case NOTE_TYPE_12TH:
		case NOTE_TYPE_24TH:
			f.Write( "]" );
			break;
		case NOTE_TYPE_16TH:
			f.Write( ")" );
			break;
		case NOTE_TYPE_32ND:
		case NOTE_TYPE_64TH:
			f.Write( "}" );
			break;
		case NOTE_TYPE_48TH:
		case NOTE_TYPE_192ND:
		case NoteType_Invalid:
			f.Write( "'" );
			break;
		default:
			ASSERT(0);
			// fall though
		}
		f.PutLine( "" );
	}
}
void ScoreKeeperMAX2::Load(
		const vector<Song*>& apSongs,
		const vector<Steps*>& apSteps,
		const vector<AttackArray> &asModifiers )
{
	m_apSteps = apSteps;
	ASSERT( apSongs.size() == apSteps.size() );
	ASSERT( apSongs.size() == asModifiers.size() );

	/* True if a jump is one to combo, false if combo is purely based on tap count. */
	m_bComboIsPerRow = THEME->GetMetricB( "Gameplay", "ComboIsPerRow" );
	m_MinScoreToContinueCombo = (TapNoteScore) THEME->GetMetricI( "Gameplay", "MinScoreToContinueCombo" );
	m_MinScoreToMaintainCombo = (TapNoteScore) THEME->GetMetricI( "Gameplay", "MinScoreToMaintainCombo" );

	//
	// Fill in STATSMAN->m_CurStageStats, calculate multiplier
	//
	int iTotalPossibleDancePoints = 0;
	int iTotalPossibleGradePoints = 0;
	for( unsigned i=0; i<apSteps.size(); i++ )
	{
		Song* pSong = apSongs[i];
		ASSERT( pSong );
		Steps* pSteps = apSteps[i];
		ASSERT( pSteps );
		const AttackArray &aa = asModifiers[i];
		NoteData ndTemp;
		pSteps->GetNoteData( ndTemp );

		/* We might have been given lots of songs; don't keep them in memory uncompressed. */
		pSteps->Compress();

		const Style* pStyle = GAMESTATE->GetCurrentStyle();
		NoteData nd;
		pStyle->GetTransformedNoteDataForStyle( m_pPlayerState->m_PlayerNumber, ndTemp, nd );

		/* Compute RadarValues before applying any user-selected mods.  Apply
		 * Course mods and count them in the "pre" RadarValues because they're
		 * forced and not chosen by the user.
		 */
		NoteDataUtil::TransformNoteData( nd, aa, pSteps->m_StepsType, pSong );
		RadarValues rvPre;
		NoteDataUtil::CalculateRadarValues( nd, pSong->m_fMusicLengthSeconds, rvPre );

		/* Apply user transforms to find out how the notes will really look. 
		 *
		 * XXX: This is brittle: if we end up combining mods for a song differently
		 * than ScreenGameplay, we'll end up with the wrong data.  We should probably
		 * have eg. GAMESTATE->GetOptionsForCourse(po,so,pn) to get options based on
		 * the last call to StoreSelectedOptions and the modifiers list, but that'd
		 * mean moving the queues in ScreenGameplay to GameState ... */
		NoteDataUtil::TransformNoteData( nd, m_pPlayerState->m_PlayerOptions, pSteps->m_StepsType );
		RadarValues rvPost;
		NoteDataUtil::CalculateRadarValues( nd, pSong->m_fMusicLengthSeconds, rvPost );
		 
		iTotalPossibleDancePoints += this->GetPossibleDancePoints( rvPre, rvPost );
		iTotalPossibleGradePoints += this->GetPossibleGradePoints( rvPre, rvPost );
	}

	m_pPlayerStageStats->iPossibleDancePoints = iTotalPossibleDancePoints;
	m_pPlayerStageStats->iPossibleGradePoints = iTotalPossibleGradePoints;

	m_iScoreRemainder = 0;
	m_iCurToastyCombo = 0; 
	m_iMaxScoreSoFar = 0;
	m_iPointBonus = 0;
	m_iNumTapsAndHolds = 0;
	m_bIsLastSongInCourse = false;

	memset( m_ComboBonusFactor, 0, sizeof(m_ComboBonusFactor) );
	switch( PREFSMAN->m_ScoringType )
	{
	case PrefsManager::SCORING_MAX2:
		m_iRoundTo = 1;
		break;
	case PrefsManager::SCORING_5TH:
		m_iRoundTo = 5;
		if (!GAMESTATE->IsCourseMode())
		{
			m_ComboBonusFactor[TNS_MARVELOUS] = 55;
			m_ComboBonusFactor[TNS_PERFECT] = 55;
			m_ComboBonusFactor[TNS_GREAT] = 33;
		}
		break;
	default:
		ASSERT(0);
	}

}
Beispiel #5
0
void ScreenHowToPlay::Init()
{
	ScreenAttract::Init();

	if( (bool)USE_PAD && DoesFileExist( GetAnimPath(ANIM_DANCE_PAD) ) )
	{
		m_pmDancePad = new Model;
		m_pmDancePad->SetName( "Pad" );
		m_pmDancePad->LoadMilkshapeAscii( GetAnimPath(ANIM_DANCE_PAD) );
		m_pmDancePad->SetRotationX( 35 );
		LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_pmDancePad );
	}
	
	// Display random character
	vector<Character*> vpCharacters;
	CHARMAN->GetCharacters( vpCharacters );
	if( (bool)USE_CHARACTER && vpCharacters.size() && HaveAllCharAnimations() )
	{
		Character* rndchar = CHARMAN->GetRandomCharacter();

		RString sModelPath = rndchar->GetModelPath();
		if( sModelPath != "" )
		{
			m_pmCharacter = new Model;
			m_pmCharacter->SetName( "Character" );
			m_pmCharacter->LoadMilkshapeAscii( rndchar->GetModelPath() );
			m_pmCharacter->LoadMilkshapeAsciiBones( "Step-LEFT", GetAnimPath( ANIM_LEFT ) );
			m_pmCharacter->LoadMilkshapeAsciiBones( "Step-DOWN", GetAnimPath( ANIM_DOWN ) );
			m_pmCharacter->LoadMilkshapeAsciiBones( "Step-UP", GetAnimPath( ANIM_UP ) );
			m_pmCharacter->LoadMilkshapeAsciiBones( "Step-RIGHT", GetAnimPath( ANIM_RIGHT ) );
			m_pmCharacter->LoadMilkshapeAsciiBones( "Step-JUMPLR", GetAnimPath( ANIM_JUMPLR ) );
			RString sRestFile = rndchar->GetRestAnimationPath();
			ASSERT( !sRestFile.empty() );
			m_pmCharacter->LoadMilkshapeAsciiBones( "rest",rndchar->GetRestAnimationPath() );
			m_pmCharacter->SetDefaultAnimation( "rest" );
			m_pmCharacter->PlayAnimation( "rest" );				// Stay bouncing after a step has finished animating.
			
			m_pmCharacter->SetRotationX( 40 );
			m_pmCharacter->SetCullMode( CULL_NONE );	// many of the models floating around have the vertex order flipped
			LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_pmCharacter );
		}
	}
	
	GAMESTATE->SetCurrentStyle( GAMEMAN->GetHowToPlayStyleForGame(GAMESTATE->m_pCurGame) );

	if( USE_PLAYER )
	{
		m_pLifeMeterBar = new LifeMeterBar;
		m_pLifeMeterBar->SetName("LifeMeterBar");
		m_pLifeMeterBar->Load( GAMESTATE->m_pPlayerState[PLAYER_1], &STATSMAN->m_CurStageStats.m_player[PLAYER_1] );
		LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_pLifeMeterBar );
		m_pLifeMeterBar->FillForHowToPlay( NUM_W2S, NUM_MISSES );


		SMLoader::LoadFromSMFile( THEME->GetPathO(m_sName, "steps"), m_Song, false );
		m_Song.AddAutoGenNotes();

		const Style* pStyle = GAMESTATE->GetCurrentStyle();
		
		Steps *pSteps = SongUtil::GetStepsByDescription( &m_Song, pStyle->m_StepsType, "" );
		ASSERT_M( pSteps != NULL, ssprintf("%i", pStyle->m_StepsType) );

		NoteData tempNoteData;
		pSteps->GetNoteData( tempNoteData );
		pStyle->GetTransformedNoteDataForStyle( PLAYER_1, tempNoteData, m_NoteData );

		GAMESTATE->m_pCurSong.Set( &m_Song );
		GAMESTATE->m_bGameplayLeadIn.Set( false );
		GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerController = PC_AUTOPLAY;

		m_Player->Init( 
			"Player",
			GAMESTATE->m_pPlayerState[PLAYER_1], 
			NULL,
			m_pLifeMeterBar, 
			NULL, 
			NULL, 
			NULL, 
			NULL, 
			NULL, 
			NULL );
		m_Player.Load( m_NoteData );
		m_Player->SetName( "Player" );
		this->AddChild( m_Player );
		LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_Player );

		// Don't show judgement
		PO_GROUP_ASSIGN( GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions, ModsLevel_Stage, m_fBlind, 1.0f );
		GAMESTATE->m_MasterPlayerNumber = PLAYER_1;
		GAMESTATE->m_bDemonstrationOrJukebox = true;
	}

	// deferred until after the player, so the notes go under it
	if( m_pLifeMeterBar )
		this->AddChild( m_pLifeMeterBar );
	if( m_pmDancePad )
		this->AddChild( m_pmDancePad );
	if( m_pmCharacter )
		this->AddChild( m_pmCharacter );

	m_fFakeSecondsIntoSong = 0;

	this->MoveToTail( &m_In );
	this->MoveToTail( &m_Out );
}