re-wrote score/statistics tracking

This commit is contained in:
Chris Danford
2002-07-28 20:28:37 +00:00
parent e07060fa08
commit f9046674fb
59 changed files with 1027 additions and 910 deletions
+5 -5
View File
@@ -20,30 +20,30 @@
// fYOffset is a vertical position in pixels relative to the center.
// (positive if has not yet been stepped on, negative if has already passed).
// The ArrowEffect is applied in this stage.
float ArrowGetYOffset( const PlayerOptions& po, float fStepIndex, float fSongBeat );
float ArrowGetYOffset( const PlayerNumber pn, float fStepIndex );
// fXPos is a horizontal position in pixels relative to the center of the field.
// This depends on the column of the arrow and possibly the Arrow effect and
// fYOffset (in the case of EFFECT_DRUNK).
float ArrowGetXPos( const PlayerOptions& po, int iCol, float fYOffset, float fSongBeat );
float ArrowGetXPos( const PlayerNumber pn, int iCol, float fYOffset );
// fRotation is Z rotation of an arrow. This will depend on the column of
// the arrow and possibly the Arrow effect and the fYOffset (in the case of
// EFFECT_DIZZY).
float ArrowGetRotation( const PlayerOptions& po, int iCol, float fYOffset );
float ArrowGetRotation( const PlayerNumber pn, int iCol, float fYOffset );
// fYPos is the position of the note in pixels relative to the center.
// (positive if has not yet been stepped on, negative if has already passed).
// This value is fYOffset with bReverseScroll and fScrollSpeed factored in.
float ArrowGetYPos( const PlayerOptions& po, float fYOffset );
float ArrowGetYPos( const PlayerNumber pn, float fYOffset );
// fAlpha is the transparency of the arrow. It depends on fYPos and the
// ArrowAppearance.
float ArrowGetAlpha( const PlayerOptions& po, float fYPos );
float ArrowGetAlpha( const PlayerNumber pn, float fYPos );
#endif
+15
View File
@@ -19,6 +19,8 @@
#include "RageException.h"
#include "RageLog.h"
#include "MsdFile.h"
#include "PlayerOptions.h"
#include "SongOptions.h"
void Course::LoadFromCRSFile( CString sPath, CArray<Song*,Song*> &apSongs )
@@ -161,6 +163,19 @@ D3DXCOLOR Course::GetColor()
return D3DXCOLOR(0,1,0,1); // green
}
void Course::GetPlayerOptions( PlayerOptions* pPO_out )
{
*pPO_out = PlayerOptions();
}
void Course::GetSongOptions( SongOptions* pSO_out )
{
*pSO_out = SongOptions();
pSO_out->m_LifeType = (m_iLives==-1) ? SongOptions::LIFE_BAR : SongOptions::LIFE_BATTERY;
if( m_iLives != -1 )
pSO_out->m_iBatteryLives = m_iLives;
}
//
// Sorting stuff
//
+4 -2
View File
@@ -11,7 +11,8 @@
*/
#include "GameConstantsAndTypes.h"
#include "PlayerOptions.h"
struct PlayerOptions;
struct SongOptions;
class Song;
struct Notes;
@@ -40,8 +41,9 @@ public:
bool m_bRepeat; // repeat after last song?
int m_iLives; // -1 means use bar life meter
CString m_sModifiers; // contains player options and song options
// PlayerOptions m_PlayerOptions;
void GetPlayerOptions( PlayerOptions* pPO_out );
void GetSongOptions( SongOptions* pSO_out);
void LoadFromCRSFile( CString sPath, CArray<Song*,Song*> &apSongs );
void CreateFromGroupAndDifficultyClass( CString sGroupName, DifficultyClass dc, CArray<Song*,Song*> &apSongsInGroup );
+4 -10
View File
@@ -413,14 +413,6 @@ inline NotesType StyleToNotesType ( Style s )
*/
///////////////////////////
// Options stuff
///////////////////////////
///////////////////////////
// Scoring stuff
@@ -432,7 +424,8 @@ enum TapNoteScore {
TNS_BOO,
TNS_GOOD,
TNS_GREAT,
TNS_PERFECT,
TNS_PERFECT,
NUM_TAP_NOTE_SCORES
};
inline int TapNoteScoreToDancePoints( TapNoteScore tns )
@@ -460,7 +453,8 @@ enum HoldNoteScore
{
HNS_NONE, // this HoldNote has not been scored yet
HNS_OK, // the HoldNote has passed and was successfully held all the way through
HNS_NG // the HoldNote has passed and they missed it
HNS_NG, // the HoldNote has passed and they missed it
NUM_HOLD_NOTE_SCORES
};
+63 -20
View File
@@ -11,7 +11,6 @@
*/
#include "GameConstantsAndTypes.h"
#include "GameplayStatistics.h"
#include "PlayerOptions.h"
#include "SongOptions.h"
@@ -30,23 +29,9 @@ public:
~GameState();
void Reset();
Song* m_pCurSong;
Notes* m_pCurNotes[NUM_PLAYERS];
Course* m_pCurCourse;
int m_iCoursePossibleDancePoints;
// Info used during gameplay
// Let lots of classes access the music beat here so we don't have to pass it around everywhere
float m_fMusicSeconds;
float m_fMusicBeat;
float m_fCurBPS;
bool m_bFreeze;
CArray<GameplayStatistics,GameplayStatistics> m_aGameplayStatistics; // for passing from Dancing to Results
GameplayStatistics& GetLatestGameplayStatistics();
//
// Main State Info
//
Game m_CurGame;
Style m_CurStyle;
PlayerNumber m_MasterPlayerNumber;
@@ -57,13 +42,13 @@ public:
bool IsPlayerEnabled( PlayerNumber pn );
bool IsPlayerEnabled( int p ) { return IsPlayerEnabled( (PlayerNumber)p ); }; // for those too lasy to cast all those p's to a PlayerNumber
CString m_sLoadingMessage;
CString m_sPreferredGroup;
DifficultyClass m_PreferredDifficultyClass[NUM_PLAYERS];
SongSortOrder m_SongSortOrder; // used by MusicWheel
PlayMode m_PlayMode;
int m_iCurrentStageIndex; // starts at 0, and is incremented with each Stage Clear
bool m_bEditing;
int m_iCurrentStageIndex; // incremented after a song ends
int GetStageIndex();
bool IsFinalStage();
@@ -72,6 +57,64 @@ public:
CString GetStageText();
D3DXCOLOR GetStageColor();
//
// State Info used during gameplay
//
Song* m_pCurSong;
Notes* m_pCurNotes[NUM_PLAYERS];
Course* m_pCurCourse;
//
// Let a lot of classes access this info here so the don't have to keep their own copies
float m_fMusicSeconds; // time into the current song
float m_fSongBeat;
float m_fCurBPS;
bool m_bFreeze; // in the middle of a freeze
void ResetMusicStatistics(); // Clear the values above
CArray<Song*,Song*> m_apSongsPlayed; // an array of completed songs.
// This is useful for the final evaluation screen,
// and used to calculate the time into a course
float GetElapsedSeconds(); // Arcade: time into current song. Oni/Endless: time into current course
float m_fSecondsBeforeFail[NUM_PLAYERS];// -1 means not yet failed
// In Arcade, is the time into the current stage before failing.
// In Oni and Endless this is the time into the current course before failing
int m_iStagesIntoCourse[NUM_PLAYERS]; // In Arcade, this value is meaningless.
// In Oni and Endless, this is the number of songs played before failing.
bool m_bUsedAutoPlayer; // Used autoplayer at any time during any stage/course/song
float GetPlayerSurviveTime( PlayerNumber p );
//
// Statistics for: Arcade: for the current stage. Oni/Endless: for current course
//
int m_iPossibleDancePoints[NUM_PLAYERS];
int m_iActualDancePoints[NUM_PLAYERS]; // In Endless, possible dance points is -1.
int m_TapNoteScores[NUM_PLAYERS][NUM_TAP_NOTE_SCORES];
int m_HoldNoteScores[NUM_PLAYERS][NUM_HOLD_NOTE_SCORES];
int m_iMaxCombo[NUM_PLAYERS];
float m_fScore[NUM_PLAYERS];
float m_fRadarPossible[NUM_PLAYERS][NUM_RADAR_VALUES]; // filled in by ScreenGameplay on end of notes
float m_fRadarActual[NUM_PLAYERS][NUM_RADAR_VALUES]; // filled in by ScreenGameplay on end of notes
void ResetStageStatistics(); // Clear the values above
void AccumulateStageStatistics(); // Accumulate values above into the values below
// Only used in final evaluation screen in play mode Arcade.
// Before being displayed, these values should be normalized by dividing by number of stages
int m_iAccumPossibleDancePoints[NUM_PLAYERS];
int m_iAccumActualDancePoints[NUM_PLAYERS]; // In Endless, possible dance points is -1.
int m_AccumTapNoteScores[NUM_PLAYERS][NUM_TAP_NOTE_SCORES];
int m_AccumHoldNoteScores[NUM_PLAYERS][NUM_HOLD_NOTE_SCORES];
int m_iAccumMaxCombo[NUM_PLAYERS];
float m_fAccumScore[NUM_PLAYERS];
float m_fAccumRadarPossible[NUM_PLAYERS][NUM_RADAR_VALUES];
float m_fAccumRadarActual[NUM_PLAYERS][NUM_RADAR_VALUES];
PlayerOptions m_PlayerOptions[NUM_PLAYERS];
SongOptions m_SongOptions;
-6
View File
@@ -26,11 +26,6 @@ void GhostArrow::Update( float fDeltaTime )
Sprite::Update( fDeltaTime );
}
void GhostArrow::SetBeat( const float fSongBeat )
{
//SetState( fmodf(fSongBeat,1)<0.25 ? 1 : 0 );
}
void GhostArrow::Step( TapNoteScore score )
{
switch( score )
@@ -47,5 +42,4 @@ void GhostArrow::Step( TapNoteScore score )
D3DXCOLOR colorTween = GetDiffuseColor();
colorTween.a = 0;
SetTweenDiffuseColor( colorTween );
}
-3
View File
@@ -22,9 +22,6 @@ public:
virtual void Update( float fDeltaTime );
void SetBeat( const float fSongBeat );
void Step( TapNoteScore score );
float m_fVisibilityCountdown;
};
+13 -11
View File
@@ -1,8 +1,15 @@
#include "stdafx.h"
//
// GhostArrowBright.cpp: implementation of the GhostArrowBright class.
//
//////////////////////////////////////////////////////////////////////
/*
-----------------------------------------------------------------------------
Class: GhostArrowBright
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Ben Nordstrom
Chris Danford
-----------------------------------------------------------------------------
*/
#include "GhostArrowBright.h"
#include "PrefsManager.h"
@@ -11,10 +18,6 @@
const float GRAY_ARROW_TWEEN_TIME = 0.5f;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
GhostArrowBright::GhostArrowBright()
{
// Load( THEME->GetPathTo(GRAPHIC_BRIGHT_GHOST_ARROW) );
@@ -22,9 +25,9 @@ GhostArrowBright::GhostArrowBright()
TurnShadowOff();
}
void GhostArrowBright::SetBeat( const float fSongBeat )
void GhostArrowBright::Update( float fDeltaTime )
{
//SetState( fmodf(fSongBeat,1)<0.25 ? 1 : 0 );
Sprite::Update( fDeltaTime );
}
void GhostArrowBright::Step( TapNoteScore score )
@@ -44,5 +47,4 @@ void GhostArrowBright::Step( TapNoteScore score )
D3DXCOLOR colorTween = GetDiffuseColor();
colorTween.a = 0;
SetTweenDiffuseColor( colorTween );
}
+11 -16
View File
@@ -1,33 +1,28 @@
#pragma once
/*
-----------------------------------------------------------------------------
File: GhostArrowBright.h
Class: GhostArrowBright
Desc: Class used to represent a color arrow on the screen.
Desc: Ghost arrow used when over 100 combo.
Copyright (c) 2001 Ben Norstrom. All rights reserved.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Ben Nordstrom
Chris Danford
-----------------------------------------------------------------------------
*/
class GhostArrowBright;
#ifndef _GhostArrowBright_H_
#define _GhostArrowBright_H_
#include "Sprite.h"
#include "Notes.h"
#include "GameConstantsAndTypes.h"
class GhostArrowBright : public Sprite
{
public:
GhostArrowBright();
void SetBeat( const float fSongBeat );
virtual void Update( float fDeltaTime );
void Step( TapNoteScore score );
float m_fVisibilityCountdown;
};
protected:
#endif
};
+5 -10
View File
@@ -25,11 +25,12 @@ GhostArrowRow::GhostArrowRow()
m_iNumCols = 0;
}
void GhostArrowRow::Load( PlayerNumber pn, StyleDef* pStyleDef, PlayerOptions po )
void GhostArrowRow::Load( PlayerNumber pn )
{
m_PlayerOptions = po;
m_PlayerNumber = pn;
GameDef* pGameDef = GAMESTATE->GetCurrentGameDef();
StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
m_iNumCols = pStyleDef->m_iColsPerPlayer;
@@ -47,19 +48,13 @@ void GhostArrowRow::Load( PlayerNumber pn, StyleDef* pStyleDef, PlayerOptions po
}
void GhostArrowRow::Update( float fDeltaTime, float fSongBeat )
void GhostArrowRow::Update( float fDeltaTime )
{
m_fSongBeat = fSongBeat;
for( int c=0; c<m_iNumCols; c++ )
{
m_GhostArrowRow[c].Update( fDeltaTime );
m_GhostArrowRowBright[c].Update( fDeltaTime );
m_HoldGhostArrowRow[c].Update( fDeltaTime );
m_GhostArrowRow[c].SetBeat( fSongBeat );
m_GhostArrowRowBright[c].SetBeat( fSongBeat );
m_HoldGhostArrowRow[c].SetBeat( fSongBeat );
}
}
@@ -67,7 +62,7 @@ void GhostArrowRow::DrawPrimitives()
{
for( int c=0; c<m_iNumCols; c++ )
{
float fX = ArrowGetXPos( m_PlayerOptions, c, 0, m_fSongBeat );
float fX = ArrowGetXPos( m_PlayerNumber, c, 0 );
m_GhostArrowRow[c].SetX( fX );
m_GhostArrowRowBright[c].SetX( fX );
m_HoldGhostArrowRow[c].SetX( fX );
+3 -4
View File
@@ -23,18 +23,17 @@ class GhostArrowRow : public ActorFrame
{
public:
GhostArrowRow();
void Update( float fDeltaTime, float fSongBeat );
virtual void Update( float fDeltaTime );
virtual void DrawPrimitives();
void Load( PlayerNumber pn, StyleDef* pStyleDef, PlayerOptions po );
void Load( PlayerNumber pn );
void TapNote( int iCol, TapNoteScore score, bool bBright );
void HoldNote( int iCol );
protected:
int m_iNumCols;
float m_fSongBeat;
PlayerOptions m_PlayerOptions;
PlayerNumber m_PlayerNumber;
GhostArrow m_GhostArrowRow[MAX_NOTE_TRACKS];
GhostArrowBright m_GhostArrowRowBright[MAX_NOTE_TRACKS];
+7 -3
View File
@@ -13,8 +13,10 @@
#include "GrayArrow.h"
#include "PrefsManager.h"
#include "GameState.h"
const float GRAY_ARROW_POP_UP_TIME = 0.15f;
const float GRAY_ARROW_POP_UP_TIME = 0.15f;
GrayArrow::GrayArrow()
@@ -22,9 +24,11 @@ GrayArrow::GrayArrow()
StopAnimating();
}
void GrayArrow::SetBeat( const float fSongBeat )
void GrayArrow::Update( float fDeltaTime )
{
int iNewState = (int)( fmod(fSongBeat,1) * Sprite::GetNumStates() );
Sprite::Update( fDeltaTime );
int iNewState = (int)( fmod(GAMESTATE->m_fSongBeat,1) * Sprite::GetNumStates() );
if( iNewState < 0 )
iNewState += Sprite::GetNumStates();
SetState( iNewState );
+1 -1
View File
@@ -23,7 +23,7 @@ class GrayArrow : public Sprite
public:
GrayArrow();
virtual void SetBeat( const float fSongBeat );
virtual void Update( float fDeltaTime );
void Step();
};
+6 -8
View File
@@ -26,11 +26,12 @@ GrayArrowRow::GrayArrowRow()
m_iNumCols = 0;
}
void GrayArrowRow::Load( PlayerNumber pn, StyleDef* pStyleDef, PlayerOptions po )
void GrayArrowRow::Load( PlayerNumber pn )
{
m_PlayerOptions = po;
m_PlayerNumber = pn;
GameDef* pGameDef = GAMESTATE->GetCurrentGameDef();
StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
m_iNumCols = pStyleDef->m_iColsPerPlayer;
@@ -42,26 +43,23 @@ void GrayArrowRow::Load( PlayerNumber pn, StyleDef* pStyleDef, PlayerOptions po
}
void GrayArrowRow::Update( float fDeltaTime, float fSongBeat )
void GrayArrowRow::Update( float fDeltaTime )
{
m_fSongBeat = fSongBeat;
for( int c=0; c<m_iNumCols; c++ )
{
m_GrayArrow[c].Update( fDeltaTime );
m_GrayArrow[c].SetBeat( fSongBeat );
}
}
void GrayArrowRow::DrawPrimitives()
{
if( m_PlayerOptions.m_bDark )
if( GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_bDark )
return;
for( int c=0; c<m_iNumCols; c++ )
{
// set arrow X
float fX = ArrowGetXPos( m_PlayerOptions, c, 0, m_fSongBeat );
float fX = ArrowGetXPos( m_PlayerNumber, c, 0 );
m_GrayArrow[c].SetX( fX );
+5 -5
View File
@@ -20,17 +20,17 @@ class GrayArrowRow : public ActorFrame
{
public:
GrayArrowRow();
virtual void Update( float fDeltaTime, float fSongBeat );
virtual void DrawPrimitives();
void Load( PlayerNumber pn, StyleDef* pStyleDef, PlayerOptions po );
void Load( PlayerNumber pn );
virtual void Update( float fDeltaTime );
virtual void DrawPrimitives();
void Step( int iCol );
protected:
int m_iNumCols;
float m_fSongBeat;
PlayerOptions m_PlayerOptions;
PlayerNumber m_PlayerNumber;
GrayArrow m_GrayArrow[MAX_NOTE_TRACKS];
};
+2 -1
View File
@@ -20,7 +20,7 @@
float RADAR_VALUE_ROTATION( int iValueIndex ) { return D3DX_PI/2 + D3DX_PI*2 / 5.0f * iValueIndex; }
const float RADAR_EDGE_WIDTH = 2;
const float RADAR_EDGE_WIDTH = 3;
GrooveRadar::GrooveRadar()
{
@@ -81,6 +81,7 @@ void GrooveRadar::TweenOffScreen()
{
for( int c=0; c<NUM_RADAR_CATEGORIES; c++ )
{
m_sprRadarLabels[c].StopTweening();
m_sprRadarLabels[c].BeginTweening( 0.2f );
m_sprRadarLabels[c].SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) );
}
+18 -20
View File
@@ -1,8 +1,15 @@
#include "stdafx.h"
//
// HoldGhostArrow.cpp: implementation of the GhostArrow class.
//
//////////////////////////////////////////////////////////////////////
/*
-----------------------------------------------------------------------------
Class: HoldGhostArrow
Desc: A graphic displayed in the HoldJudgement during Dancing.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Ben Nordstrom
Chris Danford
-----------------------------------------------------------------------------
*/
#include "HoldGhostArrow.h"
#include "PrefsManager.h"
@@ -12,11 +19,6 @@
const float HOLD_GHOST_ARROW_TWEEN_TIME = 0.5f;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
HoldGhostArrow::HoldGhostArrow()
{
m_bWasSteppedOnLastFrame = false;
@@ -24,7 +26,7 @@ HoldGhostArrow::HoldGhostArrow()
// LoadFromSpriteFile( THEME->GetPathTo(GRAPHIC_HOLD_GHOST_ARROW) );
SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
SetZoom( 1.1f );
// SetZoom( 1.1f );
}
void HoldGhostArrow::Update( float fDeltaTime )
@@ -32,17 +34,13 @@ void HoldGhostArrow::Update( float fDeltaTime )
Sprite::Update( fDeltaTime );
if( m_bWasSteppedOnLastFrame )
{
m_fHeatLevel += fDeltaTime * 4;
if( m_fHeatLevel >= 1 )
m_fHeatLevel = 1;
}
else
{
m_fHeatLevel -= fDeltaTime * 4;
if( m_fHeatLevel < 0 )
m_fHeatLevel = 0;
}
CLAMP( m_fHeatLevel, 0, 1 );
// if( m_fHeatLevel > 0 )
// printf( "m_fHeatLevel = %f\n", m_fHeatLevel );
int iStateNum = (int)min( m_fHeatLevel * GetNumStates(), GetNumStates()-1 );
SetState( iStateNum );
@@ -60,9 +58,9 @@ void HoldGhostArrow::Update( float fDeltaTime )
m_bWasSteppedOnLastFrame = false; // reset for next frame
}
void HoldGhostArrow::SetBeat( const float fSongBeat )
void HoldGhostArrow::DrawPrimitives()
{
//SetState( fmod(fSongBeat,1)<0.25 ? 1 : 0 );
Sprite::DrawPrimitives();
}
void HoldGhostArrow::Step()
+8 -15
View File
@@ -1,23 +1,17 @@
#pragma once
/*
-----------------------------------------------------------------------------
File: HoldGhostArrow.h
Class: HoldGhostArrow
Desc: Class used to represent a color arrow on the screen.
Desc: The "electricity around the stationary arrow as it's pressing a HoldNote.
Copyright (c) 2001 Ben Norstrom. All rights reserved.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Ben Nordstrom
Chris Danford
-----------------------------------------------------------------------------
*/
class HoldGhostArrow;
#ifndef _HoldGhostArrow_H_
#define _HoldGhostArrow_H_
#include "Sprite.h"
#include "Notes.h"
class HoldGhostArrow : public Sprite
{
@@ -25,12 +19,11 @@ public:
HoldGhostArrow();
virtual void Update( float fDeltaTime );
virtual void DrawPrimitives();
void SetBeat( const float fSongBeat );
void Step();
bool m_bWasSteppedOnLastFrame;
float m_fHeatLevel; // effects brightness of electricity - between 0 and 1
float m_fHeatLevel; // brightness - between 0 and 1
};
#endif
+5 -6
View File
@@ -21,21 +21,20 @@ class Song;
class LifeMeter : public ActorFrame
{
public:
LifeMeter() { m_fSongBeat = 0; };
LifeMeter() {};
virtual ~LifeMeter() {};
virtual void Load( PlayerNumber p, const PlayerOptions &po ) { m_PlayerNumber = p; m_po = po; }
virtual void SetBeat( float fSongBeat ) { m_fSongBeat = fSongBeat; };
virtual void Load( PlayerNumber p ) { m_PlayerNumber = p; }
virtual void Update( float fDeltaTime ) { ActorFrame::Update(fDeltaTime); };
virtual void NextSong( Song* pSong ) {};
virtual void SongEnded() {};
virtual void ChangeLife( TapNoteScore score ) = 0;
virtual void OnDancePointsChange() = 0; // look in GAMESTATE and update the display
virtual bool IsInDanger() = 0;
virtual bool IsHot() = 0;
virtual bool IsFailing() = 0;
virtual bool FailedEarlier() = 0;
protected:
float m_fSongBeat;
PlayerNumber m_PlayerNumber;
PlayerOptions m_po;
};
+4 -4
View File
@@ -57,11 +57,11 @@ LifeMeterBar::LifeMeterBar()
ResetBarVelocity();
}
void LifeMeterBar::Load( PlayerNumber p, const PlayerOptions &po )
void LifeMeterBar::Load( PlayerNumber pn )
{
LifeMeter::Load( p, po );
LifeMeter::Load( pn );
if( p == PLAYER_2 )
if( pn == PLAYER_2 )
m_frame.SetZoomX( -1 );
}
@@ -139,7 +139,7 @@ bool LifeMeterBar::FailedEarlier()
void LifeMeterBar::Update( float fDeltaTime )
{
ActorFrame::Update( fDeltaTime );
LifeMeter::Update( fDeltaTime );
float fDelta = m_fLifePercentage - m_fTrailingLifePercentage;
m_fLifeVelocity += fDelta * fDeltaTime; // accelerate
+2 -3
View File
@@ -20,12 +20,13 @@ class LifeMeterBar : public LifeMeter
public:
LifeMeterBar();
virtual void Load( PlayerNumber p, const PlayerOptions &po );
virtual void Load( PlayerNumber pn );
virtual void Update( float fDeltaTime );
virtual void DrawPrimitives();
virtual void ChangeLife( TapNoteScore score );
virtual void OnDancePointsChange() {}; // this life meter doesn't care
virtual bool IsInDanger();
virtual bool IsHot();
virtual bool IsFailing();
@@ -41,8 +42,6 @@ private:
Sprite m_sprStreamHot;
Sprite m_sprFrame;
PlayerOptions m_PlayerOptions;
float m_fLifePercentage;
float m_fTrailingLifePercentage; // this approaches m_fLifePercentage
float m_fLifeVelocity; // how m_fTrailingLifePercentage approaches m_fLifePercentage
+55 -42
View File
@@ -20,7 +20,7 @@ const float BATTERY_X[NUM_PLAYERS] = { -92, +92 };
const float NUM_X[NUM_PLAYERS] = { BATTERY_X[0], BATTERY_X[1] };
const float NUM_Y = +2;
const float PERCENT_X[NUM_PLAYERS] = { +28, -28 };
const float PERCENT_X[NUM_PLAYERS] = { +20, -20 };
const float PERCENT_Y = 0;
const float BATTERY_BLINK_TIME = 1.2f;
@@ -28,8 +28,8 @@ const float BATTERY_BLINK_TIME = 1.2f;
LifeMeterBattery::LifeMeterBattery()
{
m_iMaxLives = 3;
m_iLivesLeft = m_iMaxLives;
m_iLivesLeft = GAMESTATE->m_SongOptions.m_iBatteryLives;
m_iTrailingLivesLeft = m_iLivesLeft;
m_bFailedEarlier = false;
m_fBatteryBlinkTime = 0;
@@ -59,52 +59,41 @@ LifeMeterBattery::LifeMeterBattery()
Refresh();
}
void LifeMeterBattery::Load( PlayerNumber p, const PlayerOptions &po )
void LifeMeterBattery::Load( PlayerNumber pn )
{
LifeMeter::Load( p, po );
LifeMeter::Load( pn );
m_sprFrame.SetZoomX( p==PLAYER_1 ? 1.0f : -1.0f );
m_sprBattery.SetZoomX( p==PLAYER_1 ? 1.0f : -1.0f );
m_sprBattery.SetX( BATTERY_X[p] );
m_textNumLives.SetX( NUM_X[p] );
m_sprFrame.SetZoomX( pn==PLAYER_1 ? 1.0f : -1.0f );
m_sprBattery.SetZoomX( pn==PLAYER_1 ? 1.0f : -1.0f );
m_sprBattery.SetX( BATTERY_X[pn] );
m_textNumLives.SetX( NUM_X[pn] );
m_textNumLives.SetY( NUM_Y );
m_textPercent.SetX( PERCENT_X[p] );
m_textPercent.SetX( PERCENT_X[pn] );
m_textPercent.SetY( PERCENT_Y );
m_textPercent.SetDiffuseColor( PlayerToColor(p) ); // light blue
m_textPercent.SetDiffuseColor( PlayerToColor(pn) ); // light blue
}
void LifeMeterBattery::NextSong( Song* pSong )
void LifeMeterBattery::SongEnded()
{
if( m_bFailedEarlier )
return;
m_iLivesLeft++;
m_iTrailingLivesLeft = m_iLivesLeft;
m_iLivesLeft += ( GAMESTATE->m_pCurNotes[m_PlayerNumber]->m_iMeter>=8 ? 2 : 1 );
m_iLivesLeft = min( m_iLivesLeft, GAMESTATE->m_SongOptions.m_iBatteryLives );
m_soundGainLife.Play();
Refresh();
}
void LifeMeterBattery::ChangeLife( TapNoteScore score )
{
if( m_bFailedEarlier )
return;
if( GAMESTATE->m_aGameplayStatistics.GetSize() > 0 )
{
int iActualDancePoints = 0;
for( int i=0; i<GAMESTATE->m_aGameplayStatistics.GetSize(); i++ )
iActualDancePoints += GAMESTATE->m_aGameplayStatistics[i].iActualDancePoints[m_PlayerNumber];
int iPossibleDancePoints = GAMESTATE->m_iCoursePossibleDancePoints;
float fPercentDancePoints = iActualDancePoints / (float)iPossibleDancePoints + 0.001f; // correct for rounding errors
float fNumToDisplay = fPercentDancePoints*100;
CString sNumToDisplay = ssprintf("%03.1f", fNumToDisplay);
if( sNumToDisplay.GetLength() == 3 )
sNumToDisplay = "0" + sNumToDisplay;
m_textPercent.SetText( sNumToDisplay );
}
switch( score )
{
case TNS_PERFECT:
@@ -113,16 +102,35 @@ void LifeMeterBattery::ChangeLife( TapNoteScore score )
case TNS_GOOD:
case TNS_BOO:
case TNS_MISS:
m_iTrailingLivesLeft = m_iLivesLeft;
m_iLivesLeft--;
m_soundLoseLife.Play();
Refresh();
m_fBatteryBlinkTime = BATTERY_BLINK_TIME;
break;
}
if( m_iLivesLeft == -1 )
if( m_iLivesLeft == 0 )
m_bFailedEarlier = true;
}
void LifeMeterBattery::OnDancePointsChange()
{
int iActualDancePoints = GAMESTATE->m_iActualDancePoints[m_PlayerNumber];
int iPossibleDancePoints = GAMESTATE->m_iPossibleDancePoints[m_PlayerNumber];
float fPercentDancePoints = iActualDancePoints / (float)iPossibleDancePoints + 0.00001f; // correct for rounding errors
printf( "Actual %d, Possible %d, Percent %f\n", iActualDancePoints, iPossibleDancePoints, fPercentDancePoints );
float fNumToDisplay = MAX( 0, fPercentDancePoints*100 );
CString sNumToDisplay = ssprintf("%03.1f", fNumToDisplay);
if( sNumToDisplay.GetLength() == 3 )
sNumToDisplay = "0" + sNumToDisplay;
if( iPossibleDancePoints == -1 )
sNumToDisplay = "??.?";
m_textPercent.SetText( sNumToDisplay );
}
bool LifeMeterBattery::IsInDanger()
{
return false;
@@ -145,36 +153,41 @@ bool LifeMeterBattery::FailedEarlier()
void LifeMeterBattery::Refresh()
{
if( m_iLivesLeft <= 3 )
if( m_iLivesLeft <= 4 )
{
m_textNumLives.SetText( "" );
m_sprBattery.SetState( max(m_iLivesLeft,0) );
m_sprBattery.SetState( max(m_iLivesLeft-1,0) );
}
else
{
m_textNumLives.SetText( ssprintf("x%d", m_iLivesLeft) );
m_textNumLives.SetZoom( 1.5f );
m_textNumLives.BeginTweening( 0.15f );
m_textNumLives.SetTweenZoom( 1.1f );
m_sprBattery.SetState( 3 );
}
}
void LifeMeterBattery::Update( float fDeltaTime )
{
if( m_iLivesLeft == -1 )
{
m_sprBattery.SetState( 0 );
}
else if( m_fBatteryBlinkTime > 0 )
LifeMeter::Update( fDeltaTime );
if( m_fBatteryBlinkTime > 0 )
{
m_fBatteryBlinkTime -= fDeltaTime;
int iFrameNo = m_iLivesLeft + int(m_fBatteryBlinkTime*15)%2;
int iFrame1 = m_iLivesLeft-1;
int iFrame2 = m_iTrailingLivesLeft-1;
int iFrameNo = (int(m_fBatteryBlinkTime*15)%2) ? iFrame1 : iFrame2;
CLAMP( iFrameNo, 0, 3 );
m_sprBattery.SetState( iFrameNo );
if( m_fBatteryBlinkTime < 0 )
{
m_fBatteryBlinkTime = 0;
m_sprBattery.SetState( max(m_iLivesLeft,0) );
}
}
else
{
m_fBatteryBlinkTime = 0;
int iFrameNo = m_iLivesLeft-1;
CLAMP( iFrameNo, 0, 3 );
m_sprBattery.SetState( iFrameNo );
}
}
+5 -4
View File
@@ -22,12 +22,13 @@ class LifeMeterBattery : public LifeMeter
public:
LifeMeterBattery();
virtual void Load( PlayerNumber p, const PlayerOptions &po );
virtual void Load( PlayerNumber pn );
virtual void Update( float fDeltaTime );
virtual void NextSong( Song* pSong );
virtual void SongEnded();
virtual void ChangeLife( TapNoteScore score );
virtual void OnDancePointsChange(); // look in GAMESTATE and update the display
virtual bool IsInDanger();
virtual bool IsHot();
virtual bool IsFailing();
@@ -36,8 +37,8 @@ public:
void Refresh();
private:
int m_iLivesLeft;
int m_iMaxLives;
int m_iLivesLeft; // dead when 0
int m_iTrailingLivesLeft; // lags m_iLivesLeft
bool m_bFailedEarlier;
float m_fBatteryBlinkTime; // if > 0 battery is blinking
+11 -8
View File
@@ -142,12 +142,12 @@ void MenuElements::Load( CString sBackgroundPath, CString sTopEdgePath, CString
void MenuElements::TweenTopLayerOnScreen()
{
m_frameTopBar.SetXY( CENTER_X+SCREEN_WIDTH, m_sprTopEdge.GetZoomedHeight()/2 );
m_frameTopBar.BeginTweening( MENU_ELEMENTS_TWEEN_TIME*2, TWEEN_SPRING );
m_frameTopBar.BeginTweening( MENU_ELEMENTS_TWEEN_TIME, TWEEN_SPRING );
m_frameTopBar.SetTweenX( CENTER_X );
float fOriginalZoom = m_textHelp.GetZoomY();
m_textHelp.SetZoomY( 0 );
m_textHelp.BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_textHelp.BeginTweening( MENU_ELEMENTS_TWEEN_TIME/2 );
m_textHelp.SetTweenZoomY( fOriginalZoom );
}
@@ -160,10 +160,10 @@ void MenuElements::TweenOnScreenFromMenu( ScreenMessage smSendWhenDone )
void MenuElements::TweenTopLayerOffScreen()
{
m_frameTopBar.BeginTweening( MENU_ELEMENTS_TWEEN_TIME*2, TWEEN_BIAS_END );
m_frameTopBar.BeginTweening( MENU_ELEMENTS_TWEEN_TIME, TWEEN_BIAS_END );
m_frameTopBar.SetTweenX( SCREEN_WIDTH*1.5f );
m_textHelp.BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_textHelp.BeginTweening( MENU_ELEMENTS_TWEEN_TIME/2 );
m_textHelp.SetTweenZoomY( 0 );
}
@@ -178,22 +178,24 @@ void MenuElements::TweenOffScreenToMenu( ScreenMessage smSendWhenDone )
void MenuElements::TweenBottomLayerOnScreen()
{
m_frameBottomBar.SetXY( CENTER_X, SCREEN_HEIGHT + m_sprBottomEdge.GetZoomedHeight()/2 );
m_frameBottomBar.BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_frameBottomBar.BeginTweening( MENU_ELEMENTS_TWEEN_TIME/2 );
m_frameBottomBar.SetTweenY( SCREEN_HEIGHT - m_sprBottomEdge.GetZoomedHeight()/2 );
m_sprBG.SetDiffuseColor( D3DXCOLOR(0,0,0,1) );
m_sprBG.BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_sprBG.BeginTweening( MENU_ELEMENTS_TWEEN_TIME/2 );
m_sprBG.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) );
}
void MenuElements::TweenBottomLayerOffScreen()
{
m_frameBottomBar.BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_frameBottomBar.BeginTweening( MENU_ELEMENTS_TWEEN_TIME/2 );
m_frameBottomBar.SetTweenY( SCREEN_HEIGHT + m_sprTopEdge.GetZoomedHeight() );
m_sprBG.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
m_sprBG.BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_sprBG.StopTweening();
m_sprBG.BeginTweeningQueued( MENU_ELEMENTS_TWEEN_TIME*3/2.0f ); // sleep
m_sprBG.BeginTweeningQueued( MENU_ELEMENTS_TWEEN_TIME/2 ); // fade
m_sprBG.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,1) );
}
@@ -211,6 +213,7 @@ void MenuElements::TweenOffScreenToBlack( ScreenMessage smSendWhenDone, bool bPl
{
TweenTopLayerOffScreen();
TweenBottomLayerOffScreen();
m_Invisible.SetTransitionTime( MENU_ELEMENTS_TWEEN_TIME*2 );
m_Invisible.CloseWipingRight( smSendWhenDone );
}
else
+1 -1
View File
@@ -24,7 +24,7 @@
#include "TipDisplay.h"
const float MENU_ELEMENTS_TWEEN_TIME = 0.30f;
const float MENU_ELEMENTS_TWEEN_TIME = 0.5f;
class MenuElements : public ActorFrame
+5 -1
View File
@@ -40,6 +40,10 @@ NoteData::~NoteData()
void NoteData::LoadFromSMNoteDataString( CString sSMNoteData )
{
int iNumTracks = m_iNumTracks;
NoteData::Init();
m_iNumTracks = iNumTracks;
// strip comments out of sSMNoteData
while( sSMNoteData.Find("//") != -1 )
{
@@ -780,7 +784,7 @@ float NoteData::GetAirRadarValue( float fSongSeconds )
float NoteData::GetChaosRadarValue( float fSongSeconds )
{
// count number of triplets
// count number of triplets or 16ths
int iNumChaosNotes = 0;
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
{
+1 -1
View File
@@ -135,7 +135,7 @@ float NoteDataWithScoring::GetActualChaosRadarValue( float fSongSeconds )
int iNumChaosNotesCompleted = 0;
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
{
if( !IsRowComplete(r) && GetNoteType(r) >= NOTE_12TH )
if( IsRowComplete(r) && GetNoteType(r) >= NOTE_12TH )
iNumChaosNotesCompleted++;
}
+40 -43
View File
@@ -36,20 +36,19 @@ NoteField::NoteField()
m_rectMarkerBar.TurnShadowOff();
m_rectMarkerBar.SetEffectGlowing();
m_Mode = MODE_DANCING;
m_fBeginMarker = m_fEndMarker = -1;
m_fOverrideAdd = -1;
}
void NoteField::Load( NoteData* pNoteData, PlayerNumber p, StyleDef* pStyleDef, PlayerOptions po, int iPixelsToDrawBehind, int iPixelsToDrawAhead, NoteFieldMode mode )
void NoteField::Load( NoteData* pNoteData, PlayerNumber pn, int iPixelsToDrawBehind, int iPixelsToDrawAhead )
{
m_PlayerOptions = po;
m_PlayerNumber = pn;
m_iPixelsToDrawBehind = iPixelsToDrawBehind;
m_iPixelsToDrawAhead = iPixelsToDrawAhead;
m_Mode = mode;
StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
this->CopyAll( pNoteData );
@@ -59,7 +58,7 @@ void NoteField::Load( NoteData* pNoteData, PlayerNumber p, StyleDef* pStyleDef,
CArray<D3DXCOLOR,D3DXCOLOR> arrayTweenColors;
GAMEMAN->GetTweenColors( c, arrayTweenColors );
m_ColorNote[c].Load( c, p );
m_ColorNote[c].Load( c, pn );
}
@@ -70,9 +69,8 @@ void NoteField::Load( NoteData* pNoteData, PlayerNumber p, StyleDef* pStyleDef,
ASSERT( m_iNumTracks == GAMESTATE->GetCurrentStyleDef()->m_iColsPerPlayer );
}
void NoteField::Update( float fDeltaTime, float fSongBeat )
void NoteField::Update( float fDeltaTime )
{
m_fSongBeat = fSongBeat;
m_rectMarkerBar.Update( fDeltaTime );
}
@@ -81,22 +79,22 @@ void NoteField::Update( float fDeltaTime, float fSongBeat )
void NoteField::CreateTapNoteInstance( ColorNoteInstance &cni, const int iCol, const float fIndex, const D3DXCOLOR color )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, fIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fRotation = ArrowGetRotation( m_PlayerOptions, iCol, fYOffset );
const float fXPos = ArrowGetXPos( m_PlayerOptions, iCol, fYOffset, m_fSongBeat );
const float fAlpha = ArrowGetAlpha( m_PlayerOptions, fYPos );
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fIndex );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
const float fRotation = ArrowGetRotation( m_PlayerNumber, iCol, fYOffset );
const float fXPos = ArrowGetXPos( m_PlayerNumber, iCol, fYOffset );
const float fAlpha = ArrowGetAlpha( m_PlayerNumber, fYPos );
D3DXCOLOR colorLeading, colorTrailing; // of the color part. Alpha here be overwritten with fAlpha!
if( color.a == -1 ) // indicated "NULL"
m_ColorNote[iCol].GetEdgeColorsFromIndexAndBeat( roundf(fIndex), m_fSongBeat, m_PlayerOptions.m_ColorType, colorLeading, colorTrailing );
m_ColorNote[iCol].GetEdgeColorsFromIndexAndBeat( roundf(fIndex), colorLeading, colorTrailing );
else
colorLeading = colorTrailing = color;
float fAddAlpha = m_ColorNote[iCol].GetAddAlphaFromDiffuseAlpha( fAlpha );
if( m_fOverrideAdd != -1 )
fAddAlpha = m_fOverrideAdd;
int iGrayPartFrameNo = m_ColorNote[iCol].GetGrayPartFrameNoFromIndexAndBeat( roundf(fIndex), m_fSongBeat );
int iGrayPartFrameNo = m_ColorNote[iCol].GetGrayPartFrameNoFromIndexAndBeat( roundf(fIndex), GAMESTATE->m_fSongBeat );
ColorNoteInstance instance = { fXPos, fYPos, fRotation, fAlpha, colorLeading, colorTrailing, fAddAlpha, iGrayPartFrameNo };
@@ -107,14 +105,14 @@ void NoteField::CreateHoldNoteInstance( ColorNoteInstance &cni, const bool bActi
{
const int iCol = hn.m_iTrack;
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, fIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fRotation = ArrowGetRotation( m_PlayerOptions, iCol, fYOffset );
const float fXPos = ArrowGetXPos( m_PlayerOptions, iCol, fYOffset, m_fSongBeat );
const float fAlpha = ArrowGetAlpha( m_PlayerOptions, fYPos );
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fIndex );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
const float fRotation = ArrowGetRotation( m_PlayerNumber, iCol, fYOffset );
const float fXPos = ArrowGetXPos( m_PlayerNumber, iCol, fYOffset );
const float fAlpha = ArrowGetAlpha( m_PlayerNumber, fYPos );
int iGrayPartFrameNo;
if( bActive && m_Mode == MODE_DANCING )
if( bActive )
iGrayPartFrameNo = m_ColorNote[iCol].GetGrayPartFrameNoFull();
else
iGrayPartFrameNo = m_ColorNote[iCol].GetGrayPartFrameNoClear();
@@ -135,8 +133,8 @@ void NoteField::CreateHoldNoteInstance( ColorNoteInstance &cni, const bool bActi
void NoteField::DrawMeasureBar( const int iIndex, const int iMeasureNo )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, (float)iIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, (float)iIndex );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
m_rectMeasureBar.SetXY( 0, fYPos );
m_rectMeasureBar.SetWidth( (float)(m_iNumTracks+1) * ARROW_SIZE );
@@ -153,8 +151,8 @@ void NoteField::DrawMeasureBar( const int iIndex, const int iMeasureNo )
void NoteField::DrawMarkerBar( const int iIndex )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, (float)iIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, (float)iIndex );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
m_rectMarkerBar.SetXY( 0, fYPos );
m_rectMarkerBar.SetWidth( (float)(m_iNumTracks+1) * ARROW_SIZE );
@@ -165,8 +163,8 @@ void NoteField::DrawMarkerBar( const int iIndex )
void NoteField::DrawBPMText( const int iIndex, const float fBPM )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, (float)iIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, (float)iIndex );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(1,0,0,1) );
m_textMeasureNumber.SetAddColor( D3DXCOLOR(1,1,1,cosf(TIMER->GetTimeSinceStart()*2)/2+0.5f) );
@@ -177,8 +175,8 @@ void NoteField::DrawBPMText( const int iIndex, const float fBPM )
void NoteField::DrawFreezeText( const int iIndex, const float fSecs )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, (float)iIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, (float)iIndex );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(0.8f,0.8f,0,1) );
m_textMeasureNumber.SetAddColor( D3DXCOLOR(1,1,1,cosf(TIMER->GetTimeSinceStart()*2)/2+0.5f) );
@@ -191,19 +189,18 @@ void NoteField::DrawPrimitives()
{
//LOG->WriteLine( "NoteField::DrawPrimitives()" );
if( m_fSongBeat < 0 )
m_fSongBeat = 0;
float fSongBeat = max( 0, GAMESTATE->m_fSongBeat );
int iBaseFrameNo = (int)(m_fSongBeat*2.5) % NUM_FRAMES_IN_COLOR_ARROW_SPRITE; // 2.5 is a "fudge number" :-) This should be based on BPM
int iBaseFrameNo = (int)(fSongBeat*2.5) % NUM_FRAMES_IN_COLOR_ARROW_SPRITE; // 2.5 is a "fudge number" :-) This should be based on BPM
const float fBeatsToDrawBehind = m_iPixelsToDrawBehind * (1/(float)ARROW_SIZE) * (1/m_PlayerOptions.m_fArrowScrollSpeed);
const float fBeatsToDrawAhead = m_iPixelsToDrawAhead * (1/(float)ARROW_SIZE) * (1/m_PlayerOptions.m_fArrowScrollSpeed);
const int iIndexFirstArrowToDraw = max( 0, BeatToNoteRow( m_fSongBeat - fBeatsToDrawBehind ) );
const int iIndexLastArrowToDraw = BeatToNoteRow( m_fSongBeat + fBeatsToDrawAhead );
const float fBeatsToDrawBehind = m_iPixelsToDrawBehind * (1/(float)ARROW_SIZE) * (1/GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fArrowScrollSpeed);
const float fBeatsToDrawAhead = m_iPixelsToDrawAhead * (1/(float)ARROW_SIZE) * (1/GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fArrowScrollSpeed);
const int iIndexFirstArrowToDraw = max( 0, BeatToNoteRow( fSongBeat - fBeatsToDrawBehind ) );
const int iIndexLastArrowToDraw = BeatToNoteRow( fSongBeat + fBeatsToDrawAhead );
//LOG->WriteLine( "Drawing elements %d through %d", iIndexFirstArrowToDraw, iIndexLastArrowToDraw );
if( m_Mode == MODE_EDITING )
if( GAMESTATE->m_bEditing )
{
//
// Draw measure bars
@@ -284,25 +281,25 @@ void NoteField::DrawPrimitives()
// If this note was in the past and has life > 0, then it was completed and don't draw it!
if( hn.m_iEndIndex < BeatToNoteRow(m_fSongBeat) && fLife > 0 )
if( hn.m_iEndIndex < BeatToNoteRow(fSongBeat) && fLife > 0 )
continue; // skip
const int iCol = hn.m_iTrack;
const float fHoldNoteLife = m_HoldNoteLife[i];
const bool bActive = NoteRowToBeat(hn.m_iStartIndex-1) <= m_fSongBeat && m_fSongBeat <= NoteRowToBeat(hn.m_iEndIndex); // hack: added -1 because hn.m_iStartIndex changes as note is held
const bool bActive = NoteRowToBeat(hn.m_iStartIndex-1) <= fSongBeat && fSongBeat <= NoteRowToBeat(hn.m_iEndIndex); // hack: added -1 because hn.m_iStartIndex changes as note is held
// parts of the hold
const float fStartDrawingAtBeat = froundf( (float)hn.m_iStartIndex, ROWS_BETWEEN_HOLD_BITS/m_PlayerOptions.m_fArrowScrollSpeed );
const float fStartDrawingAtBeat = froundf( (float)hn.m_iStartIndex, ROWS_BETWEEN_HOLD_BITS/GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fArrowScrollSpeed );
for( float j=fStartDrawingAtBeat;
j<=hn.m_iEndIndex;
j+=ROWS_BETWEEN_HOLD_BITS/m_PlayerOptions.m_fArrowScrollSpeed ) // for each bit of the hold
j+=ROWS_BETWEEN_HOLD_BITS/GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fArrowScrollSpeed ) // for each bit of the hold
{
// check if this arrow is off the the screen
if( j < iIndexFirstArrowToDraw || iIndexLastArrowToDraw < j)
continue; // skip this arrow
if( fLife > 0 && NoteRowToBeat(j) < m_fSongBeat )
if( fLife > 0 && NoteRowToBeat(j) < fSongBeat )
continue;
CreateHoldNoteInstance( instances[iCount++], bActive, (float)j, hn, fHoldNoteLife );
@@ -310,7 +307,7 @@ void NoteField::DrawPrimitives()
}
const bool bDrawAddPass = m_PlayerOptions.m_AppearanceType != PlayerOptions::APPEARANCE_VISIBLE;
const bool bDrawAddPass = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_AppearanceType != PlayerOptions::APPEARANCE_VISIBLE;
if( iCount > 0 )
m_ColorNote[c].DrawList( iCount, instances, bDrawAddPass );
+3 -14
View File
@@ -29,15 +29,10 @@ class NoteField : public NoteData, public ActorFrame
{
public:
NoteField();
virtual void Update( float fDeltaTime, float fSongBeat );
virtual void Update( float fDeltaTime );
virtual void DrawPrimitives();
enum NoteFieldMode {
MODE_DANCING,
MODE_EDITING,
};
void Load( NoteData* pNoteData, PlayerNumber p, StyleDef* pStyleDef, PlayerOptions po, int iPixelsToDrawBehind, int iPixelsToDrawAhead, NoteFieldMode mode );
void Load( NoteData* pNoteData, PlayerNumber pn, int iPixelsToDrawBehind, int iPixelsToDrawAhead );
void RemoveTapNoteRow( int iIndex );
void SetHoldNoteLife( int iIndex, float fLife );
@@ -55,16 +50,10 @@ protected:
inline void DrawBPMText( const int iIndex, const float fBPM );
inline void DrawFreezeText( const int iIndex, const float fBPM );
PlayerOptions m_PlayerOptions;
PlayerNumber m_PlayerNumber;
int m_iPixelsToDrawBehind;
int m_iPixelsToDrawAhead;
float m_fSongBeat;
NoteFieldMode m_Mode;
// color arrows
ColorNote m_ColorNote[MAX_NOTE_TRACKS];
+146 -112
View File
@@ -21,6 +21,7 @@
#include "InputMapper.h"
#include "SongManager.h"
#include "GameState.h"
#include "RageLog.h"
// these two items are in the
@@ -28,6 +29,8 @@ const float FRAME_JUDGE_AND_COMBO_Y = CENTER_Y;
const float JUDGEMENT_Y_OFFSET = -26;
const float COMBO_Y_OFFSET = +26;
const float FRAME_JUDGE_AND_COMBO_BEAT_TIME = 0.2f;
const float ARROWS_Y = SCREEN_TOP + ARROW_SIZE * 1.5f;
const float HOLD_JUDGEMENT_Y = ARROWS_Y + 80;
@@ -36,8 +39,6 @@ const float HOLD_ARROW_NG_TIME = 0.18f;
Player::Player()
{
m_fSongBeat = 0;
m_PlayerNumber = PLAYER_INVALID;
m_pLifeMeter = NULL;
@@ -58,58 +59,69 @@ Player::Player()
}
void Player::Load( PlayerNumber player_no, StyleDef* pStyleDef, NoteData* pNoteData, const PlayerOptions& po, LifeMeter* pLM, ScoreDisplay* pScore, int iOriginalNumNotes, int iNotesMeter )
void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore )
{
//LOG->WriteLine( "Player::Load()", );
m_PlayerNumber = pn;
m_pLifeMeter = pLM;
m_pScore = pScore;
StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
// copy note data
this->CopyAll( pNoteData );
m_iNumTapNotes = pNoteData->GetNumTapNotes();
m_iTapNotesHit = 0;
m_iMeter = GAMESTATE->m_pCurNotes[m_PlayerNumber]->m_iMeter;
// init scoring
NoteDataWithScoring::Init();
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ )
m_fHoldNoteLife[i] = 1.0f;
m_PlayerNumber = player_no;
m_PlayerOptions = po;
m_pLifeMeter = pLM;
m_pScore = pScore;
if( m_pScore )
m_pScore->Init( player_no, m_PlayerOptions, iOriginalNumNotes, iNotesMeter );
m_pScore->Init( pn );
if( !po.m_bHoldNotes )
if( !GAMESTATE->m_PlayerOptions[pn].m_bHoldNotes )
this->RemoveHoldNotes();
this->Turn( po.m_TurnType );
this->Turn( GAMESTATE->m_PlayerOptions[pn].m_TurnType );
if( po.m_bLittle )
if( GAMESTATE->m_PlayerOptions[pn].m_bLittle )
this->MakeLittle();
int iPixelsToDrawBefore = 64;
int iPixelsToDrawAfter = 320;
switch( po.m_EffectType )
switch( GAMESTATE->m_PlayerOptions[pn].m_EffectType )
{
case PlayerOptions::EFFECT_MINI: iPixelsToDrawBefore *= 2; iPixelsToDrawAfter *= 2; break;
case PlayerOptions::EFFECT_SPACE: iPixelsToDrawBefore *= 2; iPixelsToDrawAfter *= 2; break;
}
m_NoteField.Load( (NoteData*)this, player_no, pStyleDef, po, iPixelsToDrawBefore, iPixelsToDrawAfter, NoteField::MODE_DANCING );
m_NoteField.Load( (NoteData*)this, pn, iPixelsToDrawBefore, iPixelsToDrawAfter );
m_GrayArrowRow.Load( player_no, pStyleDef, po );
m_GhostArrowRow.Load( player_no, pStyleDef, po );
m_GrayArrowRow.Load( pn );
m_GhostArrowRow.Load( pn );
m_frameJudgement.SetY( FRAME_JUDGE_AND_COMBO_Y );
m_frameCombo.SetY( FRAME_JUDGE_AND_COMBO_Y );
m_Combo.SetY( po.m_bReverseScroll ? -COMBO_Y_OFFSET : COMBO_Y_OFFSET );
m_Judgement.SetY( po.m_bReverseScroll ? -JUDGEMENT_Y_OFFSET : JUDGEMENT_Y_OFFSET );
m_Combo.SetY( GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll ? -COMBO_Y_OFFSET : COMBO_Y_OFFSET );
m_Judgement.SetY( GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll ? -JUDGEMENT_Y_OFFSET : JUDGEMENT_Y_OFFSET );
for( int c=0; c<pStyleDef->m_iColsPerPlayer; c++ )
m_HoldJudgement[c].SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - HOLD_JUDGEMENT_Y : HOLD_JUDGEMENT_Y );
m_HoldJudgement[c].SetY( GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll ? SCREEN_HEIGHT - HOLD_JUDGEMENT_Y : HOLD_JUDGEMENT_Y );
for( c=0; c<pStyleDef->m_iColsPerPlayer; c++ )
m_HoldJudgement[c].SetX( (float)pStyleDef->m_ColumnInfo[player_no][c].fXOffset );
m_HoldJudgement[c].SetX( (float)pStyleDef->m_ColumnInfo[pn][c].fXOffset );
m_NoteField.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GrayArrowRow.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GhostArrowRow.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_NoteField.SetY( GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GrayArrowRow.SetY( GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GhostArrowRow.SetY( GAMESTATE->m_PlayerOptions[pn].m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
if( po.m_EffectType == PlayerOptions::EFFECT_MINI )
if( GAMESTATE->m_PlayerOptions[pn].m_EffectType == PlayerOptions::EFFECT_MINI )
{
m_NoteField.SetZoom( 0.5f );
m_GrayArrowRow.SetZoom( 0.5f );
@@ -117,16 +129,16 @@ void Player::Load( PlayerNumber player_no, StyleDef* pStyleDef, NoteData* pNoteD
}
}
void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference )
void Player::Update( float fDeltaTime )
{
//LOG->WriteLine( "Player::Update(%f, %f, %f)", fDeltaTime, fSongBeat, fMaxBeatDifference );
//LOG->WriteLine( "Player::Update(%f)", fDeltaTime );
m_fSongBeat = fSongBeat; // save song beat
const float fSongBeat = GAMESTATE->m_fSongBeat;
//
// Check for TapNote misses
//
UpdateTapNotesMissedOlderThan( m_fSongBeat-fMaxBeatDifference );
UpdateTapNotesMissedOlderThan( GAMESTATE->m_fSongBeat - GetMaxBeatDifference() );
//
@@ -149,7 +161,7 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference
// update the life
if( fStartBeat < m_fSongBeat && m_fSongBeat < fEndBeat ) // if the song beat is in the range of this hold
if( fStartBeat < fSongBeat && fSongBeat < fEndBeat ) // if the song beat is in the range of this hold
{
const bool bIsHoldingButton = INPUTMAPPER->IsButtonDown( GameI ) || PREFSMAN->m_bAutoPlay;
// if they got a bad score or haven't stepped on the corresponding tap yet
@@ -162,13 +174,13 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference
fLife += fDeltaTime/HOLD_ARROW_NG_TIME;
fLife = min( fLife, 1 ); // clamp
m_NoteField.m_HoldNotes[i].m_iStartIndex = BeatToNoteRow( m_fSongBeat ); // move the start of this Hold
m_NoteField.m_HoldNotes[i].m_iStartIndex = BeatToNoteRow( fSongBeat ); // move the start of this Hold
m_GhostArrowRow.HoldNote( hn.m_iTrack ); // update the "electric ghost" effect
}
else // !bIsHoldingButton
{
if( m_fSongBeat-fStartBeat > fMaxBeatDifference )
if( fSongBeat-fStartBeat > GetMaxBeatDifference() )
{
// Decrease life
fLife -= fDeltaTime/HOLD_ARROW_NG_TIME;
@@ -182,18 +194,18 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference
if( fLife == 0 ) // the player has not pressed the button for a long time!
{
hns = HNS_NG;
GAMESTATE->GetLatestGameplayStatistics().iActualDancePoints[m_PlayerNumber] += HoldNoteScoreToDancePoints( hns );
HandleNoteScore( hns );
m_Combo.EndCombo();
m_HoldJudgement[hn.m_iTrack].SetHoldJudgement( HNS_NG );
}
// check for OK
if( m_fSongBeat > fEndBeat ) // if this HoldNote is in the past
if( fSongBeat > fEndBeat ) // if this HoldNote is in the past
{
// At this point fLife > 0, or else we would have marked it NG above
fLife = 1;
hns = HNS_OK;
GAMESTATE->GetLatestGameplayStatistics().iActualDancePoints[m_PlayerNumber] += HoldNoteScoreToDancePoints( hns );
HandleNoteScore( hns );
m_HoldJudgement[hn.m_iTrack].SetHoldJudgement( HNS_OK );
m_NoteField.SetHoldNoteLife( i, fLife ); // update the NoteField display
}
@@ -202,23 +214,13 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference
ActorFrame::Update( fDeltaTime );
m_frameJudgement.Update( fDeltaTime );
m_frameCombo.Update( fDeltaTime );
if( m_pLifeMeter )
m_pLifeMeter->SetBeat( fSongBeat );
m_GrayArrowRow.Update( fDeltaTime, fSongBeat );
m_NoteField.Update( fDeltaTime, fSongBeat );
m_GhostArrowRow.Update( fDeltaTime, fSongBeat );
}
void Player::DrawPrimitives()
{
D3DXMATRIX matOldView, matOldProj;
if( m_PlayerOptions.m_EffectType == PlayerOptions::EFFECT_SPACE )
if( GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_EffectType == PlayerOptions::EFFECT_SPACE )
{
// save old view and projection
DISPLAY->GetDevice()->GetTransform( D3DTS_VIEW, &matOldView );
@@ -227,7 +229,7 @@ void Player::DrawPrimitives()
// construct view and project matrix
D3DXMATRIX matNewView;
if( m_PlayerOptions.m_bReverseScroll )
if( GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_bReverseScroll )
D3DXMatrixLookAtLH(
&matNewView,
&D3DXVECTOR3( CENTER_X, GetY()-300.0f, 400.0f ),
@@ -255,7 +257,7 @@ void Player::DrawPrimitives()
m_NoteField.Draw();
m_GhostArrowRow.Draw();
if( m_PlayerOptions.m_EffectType == PlayerOptions::EFFECT_SPACE )
if( GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_EffectType == PlayerOptions::EFFECT_SPACE )
{
// restire old view and projection
DISPLAY->GetDevice()->SetTransform( D3DTS_VIEW, &matOldView );
@@ -268,16 +270,17 @@ void Player::DrawPrimitives()
m_HoldJudgement[c].Draw();
}
void Player::HandlePlayerStep( float fSongBeat, int col, float fMaxBeatDiff )
void Player::Step( int col )
{
//LOG->WriteLine( "Player::HandlePlayerStep()" );
ASSERT( col >= 0 && col <= m_iNumTracks );
const float fSongBeat = GAMESTATE->m_fSongBeat;
// look for the closest matching step
int iIndexStartLookingAt = BeatToNoteRow( fSongBeat );
int iNumElementsToExamine = BeatToNoteRow( fMaxBeatDiff ); // number of elements to examine on either end of iIndexStartLookingAt
int iIndexStartLookingAt = BeatToNoteRow( GAMESTATE->m_fSongBeat );
int iNumElementsToExamine = BeatToNoteRow( GetMaxBeatDifference() ); // number of elements to examine on either end of iIndexStartLookingAt
//LOG->WriteLine( "iIndexStartLookingAt = %d, iNumElementsToExamine = %d", iIndexStartLookingAt, iNumElementsToExamine );
@@ -324,7 +327,7 @@ void Player::HandlePlayerStep( float fSongBeat, int col, float fMaxBeatDiff )
// compute the score for this hit
const float fStepBeat = NoteRowToBeat( (float)iIndexOverlappingNote );
const float fBeatsUntilStep = fStepBeat - fSongBeat;
const float fPercentFromPerfect = fabsf( fBeatsUntilStep / fMaxBeatDiff );
const float fPercentFromPerfect = fabsf( fBeatsUntilStep / GetMaxBeatDifference() );
TapNoteScore &score = m_TapNoteScores[col][iIndexOverlappingNote];
@@ -347,14 +350,14 @@ void Player::HandlePlayerStep( float fSongBeat, int col, float fMaxBeatDiff )
}
}
if( bRowDestroyed )
OnRowDestroyed( fSongBeat, col, fMaxBeatDiff, iIndexOverlappingNote );
OnRowDestroyed( col, iIndexOverlappingNote );
}
if( !bDestroyedNote )
m_GrayArrowRow.Step( col );
}
void Player::OnRowDestroyed( float fSongBeat, int col, float fMaxBeatDiff, int iIndexThatWasSteppedOn )
void Player::OnRowDestroyed( int col, int iIndexThatWasSteppedOn )
{
//LOG->WriteLine( "fBeatsUntilStep: %f, fPercentFromPerfect: %f",
// fBeatsUntilStep, fPercentFromPerfect );
@@ -365,12 +368,6 @@ void Player::OnRowDestroyed( float fSongBeat, int col, float fMaxBeatDiff, int i
if( m_TapNoteScores[t][iIndexThatWasSteppedOn] >= TNS_BOO )
score = min( score, m_TapNoteScores[t][iIndexThatWasSteppedOn] );
// update the judgement, score, and life
m_Judgement.SetJudgement( score );
if( m_pLifeMeter )
m_pLifeMeter->ChangeLife( score );
// remove this row from the NoteField
if ( ( score == TNS_PERFECT ) || ( score == TNS_GREAT ) )
m_NoteField.RemoveTapNoteRow( iIndexThatWasSteppedOn );
@@ -381,12 +378,7 @@ void Player::OnRowDestroyed( float fSongBeat, int col, float fMaxBeatDiff, int i
{
m_GhostArrowRow.TapNote( c, score, m_Combo.GetCurrentCombo()>100 ); // show the ghost arrow for this column
if( m_pScore )
m_pScore->AddToScore( score, m_Combo.GetCurrentCombo() ); // update score - called once per note in this row
// update dance points for Oni lifemeter
if( GAMESTATE->m_aGameplayStatistics.GetSize() > 0 )
GAMESTATE->GetLatestGameplayStatistics().iActualDancePoints[m_PlayerNumber] += TapNoteScoreToDancePoints( score );
HandleNoteScore( score ); // update score - called once per note in this row
// update combo - called once per note in this row
switch( score )
@@ -394,6 +386,7 @@ void Player::OnRowDestroyed( float fSongBeat, int col, float fMaxBeatDiff, int i
case TNS_PERFECT:
case TNS_GREAT:
m_Combo.ContinueCombo();
GAMESTATE->m_iMaxCombo[m_PlayerNumber] = max( GAMESTATE->m_iMaxCombo[m_PlayerNumber], m_Combo.GetCurrentCombo() );
break;
case TNS_GOOD:
case TNS_BOO:
@@ -403,21 +396,26 @@ void Player::OnRowDestroyed( float fSongBeat, int col, float fMaxBeatDiff, int i
}
}
// update the judgement, score, and life
m_Judgement.SetJudgement( score );
if( m_pLifeMeter )
m_pLifeMeter->ChangeLife( score );
// zoom the judgement and combo like a heart beat
float fStartZoom;
switch( score )
{
case TNS_PERFECT: fStartZoom = 1.5f; break;
case TNS_GREAT: fStartZoom = 1.3f; break;
case TNS_GOOD: fStartZoom = 1.2f; break;
case TNS_PERFECT: fStartZoom = 1.3f; break;
case TNS_GREAT: fStartZoom = 1.2f; break;
case TNS_GOOD: fStartZoom = 1.1f; break;
case TNS_BOO: fStartZoom = 1.0f; break;
}
m_frameJudgement.SetZoom( fStartZoom );
m_frameJudgement.BeginTweening( 0.2f );
m_frameJudgement.BeginTweening( 0.1f );
m_frameJudgement.SetTweenZoom( 1 );
m_frameCombo.SetZoom( fStartZoom );
m_frameCombo.BeginTweening( 0.2f );
m_frameCombo.BeginTweening( 0.1f );
m_frameCombo.SetTweenZoom( 1 );
}
@@ -444,6 +442,7 @@ int Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat )
m_TapNoteScores[t][r] = TNS_MISS;
iNumMissesFound++;
bFoundAMissInThisRow = true;
HandleNoteScore( TNS_MISS );
}
if( bFoundAMissInThisRow )
if( m_pLifeMeter )
@@ -461,7 +460,7 @@ int Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat )
}
void Player::CrossedRow( int iNoteRow, float fSongBeat, float fMaxBeatDiff )
void Player::CrossedRow( int iNoteRow )
{
if( PREFSMAN->m_bAutoPlay )
{
@@ -469,59 +468,94 @@ void Player::CrossedRow( int iNoteRow, float fSongBeat, float fMaxBeatDiff )
for( int t=0; t<m_iNumTracks; t++ )
{
if( m_TapNotes[t][iNoteRow] != '0' )
this->HandlePlayerStep( fSongBeat, t, fMaxBeatDiff );
this->Step( t );
}
}
}
void Player::SaveGameplayStatistics()
void Player::HandleNoteScore( TapNoteScore score )
{
GameplayStatistics& GS = GAMESTATE->m_aGameplayStatistics[GAMESTATE->m_aGameplayStatistics.GetSize()-1];
int p = m_PlayerNumber;
// update dance points for Oni lifemeter
GAMESTATE->m_iActualDancePoints[m_PlayerNumber] += TapNoteScoreToDancePoints( score );
GAMESTATE->m_TapNoteScores[m_PlayerNumber][score]++;
if( m_pLifeMeter )
m_pLifeMeter->OnDancePointsChange();
GS.iActualDancePoints[p] = 0;
for( int t=0; t<MAX_NOTE_TRACKS; t++ )
//A single step's points are calculated as follows:
//
//Let p = score multiplier (Perfect = 10, Great = 5, other = 0)
//N = total number of steps and freeze steps
//n = number of the current step or freeze step (varies from 1 to N)
//B = Base value of the song (1,000,000 X the number of feet difficulty) - All edit data is rated as 5 feet
//So, the score for one step is:
//one_step_score = p * (B/S) * n
//Where S = The sum of all integers from 1 to N (the total number of steps/freeze steps)
//
//*IMPORTANT* : Double steps (U+L, D+R, etc.) count as two steps instead of one, so if you get a double L+R on the 112th step of a song, you score is calculated with a Perfect/Great/whatever for both the 112th and 113th steps. Got it? Now, through simple algebraic manipulation
//S = 1+...+N = (1+N)*N/2 (1 through N added together)
//Okay, time for an example:
//
//So, for example, suppose we wanted to calculate the step score of a "Great" on the 57th step of a 441 step, 8-foot difficulty song (I'm just making this one up):
//
//S = (1 + 441)*441 / 2
//= 194,222 / 2
//= 97,461
//StepScore = p * (B/S) * n
//= 5 * (8,000,000 / 97,461) * 57
//= 5 * (82) * 57 (The 82 is rounded down from 82.08411...)
//= 23,370
//Remember this is just the score for the step, not the cumulative score up to the 57th step. Also, please note that I am currently checking into rounding errors with the system and if there are any, how they are resolved in the system.
//
//Note: if you got all Perfect on this song, you would get (p=10)*B, which is 80,000,000. In fact, the maximum possible score for any song is the number of feet difficulty X 10,000,000.
int p; // score multiplier
switch( score )
{
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
{
if( m_TapNotes[t][r] == '0' )
continue; // no note here
switch( m_TapNoteScores[t][r] )
{
case TNS_PERFECT: GS.perfect[p]++; break;
case TNS_GREAT: GS.great[p]++; break;
case TNS_GOOD: GS.good[p]++; break;
case TNS_BOO: GS.boo[p]++; break;
case TNS_MISS: GS.miss[p]++; break;
case TNS_NONE: break;
default: ASSERT( false );
}
GS.iActualDancePoints[p] += TapNoteScoreToDancePoints( m_TapNoteScores[t][r] );
}
case TNS_PERFECT: p = 10; break;
case TNS_GREAT: p = 5; break;
default: p = 0; break;
}
for( int i=0; i<m_iNumHoldNotes; i++ )
{
switch( m_HoldNoteScores[i] )
{
case HNS_NG: GS.ng[p]++; break;
case HNS_OK: GS.ok[p]++; break;
case HNS_NONE: break;
default: ASSERT( false );
}
GS.iActualDancePoints[p] += HoldNoteScoreToDancePoints( m_HoldNoteScores[i] );
}
GS.max_combo[p] = m_Combo.GetMaxCombo();
GS.score[p] = m_pScore ? m_pScore->GetScore() : 0;
int N = m_iNumTapNotes;
int n = m_iTapNotesHit+1;
int B = m_iMeter * 1000000;
float S = (1+N)*N/2.0f;
GS.failed[p] = m_pLifeMeter ? m_pLifeMeter->FailedEarlier() : false;
printf( "m_iNumTapNotes %d, m_iTapNotesHit %d\n", m_iNumTapNotes, m_iTapNotesHit );
for( int r=0; r<NUM_RADAR_VALUES; r++ )
{
GS.fRadarActual[p][r] = this->GetActualRadarValue( (RadarCategory)r, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
CLAMP( GS.fRadarActual[p][r], 0, 1 );
}
float one_step_score = p * (B/S) * n;
float& fScore = GAMESTATE->m_fScore[m_PlayerNumber];
ASSERT( fScore >= 0 );
fScore += one_step_score;
m_iTapNotesHit++;
ASSERT( m_iTapNotesHit <= m_iNumTapNotes );
// HACK: Correct for rounding errors that cause a 100% perfect score to be slightly off
if( m_iTapNotesHit == m_iNumTapNotes &&
fabsf( fScore - froundf(fScore,1000000) ) < 50.0f ) // close to a multiple of 1,000,000
fScore = froundf(fScore,1000000);
if( m_pScore )
m_pScore->SetScore( fScore );
}
void Player::HandleNoteScore( HoldNoteScore score )
{
// update dance points for Oni lifemeter
GAMESTATE->m_iActualDancePoints[m_PlayerNumber] += HoldNoteScoreToDancePoints( score );
GAMESTATE->m_HoldNoteScores[m_PlayerNumber][score]++;
if( m_pLifeMeter )
m_pLifeMeter->OnDancePointsChange();
// HoldNoteScores don't effect m_fScore
}
float Player::GetMaxBeatDifference()
{
return GAMESTATE->m_fCurBPS * PREFSMAN->m_fJudgeWindow * GAMESTATE->m_SongOptions.m_fMusicRate;
}
+14 -13
View File
@@ -34,32 +34,31 @@
#include "NoteDataWithScoring.h"
struct GameplayStatistics;
class Player : public NoteDataWithScoring, public ActorFrame
{
public:
Player();
void Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference );
void DrawPrimitives();
virtual void Update( float fDeltaTime );
virtual void DrawPrimitives();
void Load( PlayerNumber player_no, StyleDef *pStyleDef, NoteData* pNoteData, const PlayerOptions& po, LifeMeter* pLM, ScoreDisplay* pScore, int iOriginalNumNotes, int iNotesMeter );
void CrossedRow( int iNoteRow, float fSongBeat, float fMaxBeatDiff );
void HandlePlayerStep( float fSongBeat, int col, float fMaxBeatDiff );
int UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat );
void Load( PlayerNumber player_no, NoteData* pNoteData, LifeMeter* pLM, ScoreDisplay* pScore );
void CrossedRow( int iNoteRow );
void Step( int col );
void SaveGameplayStatistics();
void SetOverrideAdd( float fAdd ) { m_NoteField.m_fOverrideAdd = fAdd; };
float GetOverrideAdd() { return m_NoteField.m_fOverrideAdd; };
protected:
void OnRowDestroyed( float fSongBeat, int col, float fMaxBeatDiff, int iStepIndex );
int UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat );
void OnRowDestroyed( int col, int iStepIndex );
void HandleNoteScore( TapNoteScore score );
void HandleNoteScore( HoldNoteScore score );
static float GetMaxBeatDifference();
float m_fSongBeat;
PlayerNumber m_PlayerNumber;
PlayerOptions m_PlayerOptions;
float m_fHoldNoteLife[MAX_TAP_NOTE_ROWS]; // 1.0 means this HoldNote has full life.
// 0.0 means this HoldNote is dead
@@ -67,7 +66,9 @@ protected:
// m_HoldScore becomes HSS_NG.
// If the life is > 0.0 when the HoldNote ends, then
// m_HoldScore becomes HSS_OK.
int m_iNumTapNotes; // num of TapNotes for the current notes needed by scoring
int m_iTapNotesHit; // number of notes judged so far, needed by scoring
int m_iMeter; // meter of current steps, needed by scoring
GrayArrowRow m_GrayArrowRow;
NoteField m_NoteField;
-5
View File
@@ -49,11 +49,6 @@ public:
void SaveGlobalPrefsToDisk();
// AppearanceOptions (ARE saved between sessions, and saved per game)
// CString m_sAnnouncer; // need to make sure to call ANNOUNCER->SwitchAnnouncer() when this changes
// CString m_sTheme; // need to make sure to call THEME->SwitchTheme() when this changes
// CString m_sNoteSkin;
void ReadGamePrefsFromDisk();
void SaveGamePrefsToDisk();
};
+3 -2
View File
@@ -1,11 +1,12 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
File: RageSound.cpp
Class: RageSound
Desc: Sound effects library (currently a wrapper around Bass Sound Library).
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
+9
View File
@@ -19,6 +19,7 @@
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#define ZERO(x) memset(&x, 0, sizeof(x))
#define COPY(a,b) { ASSERT(sizeof(a)==sizeof(b)); memcpy(&a, &b, sizeof(a)); }
#define RECTWIDTH(rect) ((rect).right - (rect).left)
#define RECTHEIGHT(rect) ((rect).bottom - (rect).top)
@@ -33,6 +34,14 @@ inline int RECTCENTERY(RECT rect) { return rect.top + (rect.bottom-rect.top)/2;
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define clamp(val,low,high) ( max( (low), min((val),(high)) ) )
#define PI D3DX_PI
+4 -5
View File
@@ -21,14 +21,13 @@
class ScoreDisplay : public BitmapText
{
public:
virtual void Init( PlayerNumber pn, PlayerOptions po, int iOriginalNumNotes, int iNotesMeter ) = 0;
virtual void SetScore( float fNewScore ) = 0;
virtual int GetScore() = 0;
virtual void AddToScore( TapNoteScore score, int iCurCombo ) = 0;
virtual void Init( PlayerNumber pn ) { m_PlayerNumber = pn; };
virtual void Update( float fDeltaTime ) = 0;
virtual void Draw() = 0;
virtual void SetScore( float fNewScore ) = 0;
protected:
PlayerNumber m_PlayerNumber; // needed to look up statistics in GAMESTATE
};
+15 -96
View File
@@ -35,15 +35,11 @@ ScoreDisplayNormal::ScoreDisplayNormal()
}
void ScoreDisplayNormal::Init( PlayerNumber pn, PlayerOptions po, int iOriginalNumNotes, int iNotesMeter )
void ScoreDisplayNormal::Init( PlayerNumber pn )
{
m_PlayerNumber = pn;
m_PlayerOptions = po;
m_iTotalNotes = iOriginalNumNotes;
m_iNotesMeter = iNotesMeter;
//for( int i=0; i<iOriginalNumNotes; i++ )
// AddToScore( TNS_GREAT, i );
SetScore( GAMESTATE->m_fScore[pn] );
}
void ScoreDisplayNormal::SetScore( float fNewScore )
@@ -55,105 +51,28 @@ void ScoreDisplayNormal::SetScore( float fNewScore )
m_fScoreVelocity = fDelta / SCORE_TWEEN_TIME; // in score units per second
}
int ScoreDisplayNormal::GetScore()
{
return (int)m_fScore;
}
void ScoreDisplayNormal::Update( float fDeltaTime )
{
BitmapText::Update( fDeltaTime );
float fDeltaBefore = (float)m_fScore - m_fTrailingScore;
m_fTrailingScore += m_fScoreVelocity * fDeltaTime;
float fDeltaAfter = (float)m_fScore - m_fTrailingScore;
if( fDeltaBefore * fDeltaAfter < 0 ) // the sign changed
if( m_fTrailingScore != m_fScore )
{
m_fTrailingScore = (float)m_fScore;
m_fScoreVelocity = 0;
}
float fDeltaBefore = (float)m_fScore - m_fTrailingScore;
m_fTrailingScore += m_fScoreVelocity * fDeltaTime;
float fDeltaAfter = (float)m_fScore - m_fTrailingScore;
if( fDeltaBefore * fDeltaAfter < 0 ) // the sign changed
{
m_fTrailingScore = (float)m_fScore;
m_fScoreVelocity = 0;
}
CString sFormat = ssprintf( "%%%d.0f", NUM_SCORE_DIGITS );
SetText( ssprintf(sFormat, m_fTrailingScore) );
}
}
void ScoreDisplayNormal::Draw()
{
if( m_fScore == 0 )
{
CString sFormat = ssprintf( "%%%d.0d", NUM_SCORE_DIGITS );
SetText( ssprintf(sFormat, 0) );
}
else
{
CString sFormat = ssprintf( "%%%d.0f", NUM_SCORE_DIGITS );
SetText( ssprintf(sFormat, m_fTrailingScore) );
}
BitmapText::Draw();
}
void ScoreDisplayNormal::AddToScore( TapNoteScore score, int iCurCombo )
{
//A single step's points are calculated as follows:
//
//Let p = score multiplier (Perfect = 10, Great = 5, other = 0)
//N = total number of steps and freeze steps
//n = number of the current step or freeze step (varies from 1 to N)
//B = Base value of the song (1,000,000 X the number of feet difficulty) - All edit data is rated as 5 feet
//So, the score for one step is:
//one_step_score = p * (B/S) * n
//Where S = The sum of all integers from 1 to N (the total number of steps/freeze steps)
//
//*IMPORTANT* : Double steps (U+L, D+R, etc.) count as two steps instead of one, so if you get a double L+R on the 112th step of a song, you score is calculated with a Perfect/Great/whatever for both the 112th and 113th steps. Got it? Now, through simple algebraic manipulation
//S = 1+...+N = (1+N)*N/2 (1 through N added together)
//Okay, time for an example:
//
//So, for example, suppose we wanted to calculate the step score of a "Great" on the 57th step of a 441 step, 8-foot difficulty song (I'm just making this one up):
//
//S = (1 + 441)*441 / 2
//= 194,222 / 2
//= 97,461
//StepScore = p * (B/S) * n
//= 5 * (8,000,000 / 97,461) * 57
//= 5 * (82) * 57 (The 82 is rounded down from 82.08411...)
//= 23,370
//Remember this is just the score for the step, not the cumulative score up to the 57th step. Also, please note that I am currently checking into rounding errors with the system and if there are any, how they are resolved in the system.
//
//Note: if you got all Perfect on this song, you would get (p=10)*B, which is 80,000,000. In fact, the maximum possible score for any song is the number of feet difficulty X 10,000,000.
if( PREFSMAN->m_bAutoPlay )
return; // No Scoring on Autoplay!
static int iNumTimesCalled = 0;
iNumTimesCalled ++;
LOG->WriteLine("Called %d times - param %d.",iNumTimesCalled, iCurCombo);
int p; // score multiplier
switch( score )
{
case TNS_PERFECT: p = 10; break;
case TNS_GREAT: p = 5; break;
default: p = 0; break;
}
int N = m_iTotalNotes;
int n = iCurCombo+1;
int B = m_iNotesMeter * 1000000;
float S = (1+N)*N/2.0f;
int one_step_score = roundf( p * (B/S) * n );
m_fScore += one_step_score;
ASSERT( m_fScore >= 0 );
// HACK: The final total is slightly off because of rounding errors
if( fabsf(m_fScore-B*10) < 100.0f )
m_fScore = (float)B*10;
this->SetScore( m_fScore );
}
+7 -15
View File
@@ -3,7 +3,7 @@
-----------------------------------------------------------------------------
Class: ScoreDisplayNormal
Desc: A graphic displayed in the ScoreDisplayNormal during Dancing.
Desc: Shows point score during gameplay and used in some menus.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
@@ -21,23 +21,15 @@ class ScoreDisplayNormal : public ScoreDisplay
public:
ScoreDisplayNormal();
virtual void Init( PlayerNumber pn, PlayerOptions po, int iOriginalNumNotes, int iNotesMeter );
virtual void SetScore( float fNewScore );
virtual int GetScore();
virtual void AddToScore( TapNoteScore score, int iCurCombo );
virtual void Init( PlayerNumber pn );
virtual void Update( float fDeltaTime );
virtual void Draw();
virtual void SetScore( float fNewScore );
protected:
PlayerNumber m_PlayerNumber;
PlayerOptions m_PlayerOptions;
int m_iTotalNotes;
int m_iNotesMeter;
float m_fScore;
float m_fTrailingScore;
float m_fScoreVelocity;
float m_fScore; // the actual score
float m_fTrailingScore; // what is displayed temporarily
float m_fScoreVelocity; // how fast trailing approaches real score
};
+3 -97
View File
@@ -28,61 +28,27 @@ ScoreDisplayOni::ScoreDisplayOni()
// init the text
Load( THEME->GetPathTo(FONT_SCORE_NUMBERS) );
TurnShadowOff();
m_fTrailingScore = 0;
SetScore( 0 );
}
void ScoreDisplayOni::Init( PlayerNumber pn, PlayerOptions po, int iOriginalNumNotes, int iNotesMeter )
void ScoreDisplayOni::Init( PlayerNumber pn )
{
m_PlayerNumber = pn;
m_PlayerOptions = po;
m_iTotalNotes = iOriginalNumNotes;
m_iNotesMeter = iNotesMeter;
//for( int i=0; i<iOriginalNumNotes; i++ )
// AddToScore( TNS_GREAT, i );
}
void ScoreDisplayOni::SetScore( float fNewScore )
{
m_fScore = fNewScore;
float fDelta = (float)m_fScore - m_fTrailingScore;
m_fScoreVelocity = fDelta / SCORE_TWEEN_TIME; // in score units per second
}
int ScoreDisplayOni::GetScore()
{
return (int)m_fScore;
}
void ScoreDisplayOni::Update( float fDeltaTime )
{
BitmapText::Update( fDeltaTime );
float fDeltaBefore = (float)m_fScore - m_fTrailingScore;
m_fTrailingScore += m_fScoreVelocity * fDeltaTime;
float fDeltaAfter = (float)m_fScore - m_fTrailingScore;
if( fDeltaBefore * fDeltaAfter < 0 ) // the sign changed
{
m_fTrailingScore = (float)m_fScore;
m_fScoreVelocity = 0;
}
}
void ScoreDisplayOni::Draw()
{
float fSecsIntoPlay = 0;
for( int i=0; i<GAMESTATE->m_aGameplayStatistics.GetSize(); i++ )
fSecsIntoPlay += GAMESTATE->m_aGameplayStatistics[i].fSecsIntoPlay[m_PlayerNumber];
float fSecsIntoPlay = GAMESTATE->GetPlayerSurviveTime(m_PlayerNumber);
int iMinsDisplay = (int)fSecsIntoPlay/60;
int iSecsDisplay = (int)fSecsIntoPlay - iMinsDisplay*60;
int iLeftoverDisplay = int( (fSecsIntoPlay - iMinsDisplay*60 - iSecsDisplay) * 100 );
@@ -90,63 +56,3 @@ void ScoreDisplayOni::Draw()
BitmapText::Draw();
}
void ScoreDisplayOni::AddToScore( TapNoteScore score, int iCurCombo )
{
//A single step's points are calculated as follows:
//
//Let p = score multiplier (Perfect = 10, Great = 5, other = 0)
//N = total number of steps and freeze steps
//n = number of the current step or freeze step (varies from 1 to N)
//B = Base value of the song (1,000,000 X the number of feet difficulty) - All edit data is rated as 5 feet
//So, the score for one step is:
//one_step_score = p * (B/S) * n
//Where S = The sum of all integers from 1 to N (the total number of steps/freeze steps)
//
//*IMPORTANT* : Double steps (U+L, D+R, etc.) count as two steps instead of one, so if you get a double L+R on the 112th step of a song, you score is calculated with a Perfect/Great/whatever for both the 112th and 113th steps. Got it? Now, through simple algebraic manipulation
//S = 1+...+N = (1+N)*N/2 (1 through N added together)
//Okay, time for an example:
//
//So, for example, suppose we wanted to calculate the step score of a "Great" on the 57th step of a 441 step, 8-foot difficulty song (I'm just making this one up):
//
//S = (1 + 441)*441 / 2
//= 194,222 / 2
//= 97,461
//StepScore = p * (B/S) * n
//= 5 * (8,000,000 / 97,461) * 57
//= 5 * (82) * 57 (The 82 is rounded down from 82.08411...)
//= 23,370
//Remember this is just the score for the step, not the cumulative score up to the 57th step. Also, please note that I am currently checking into rounding errors with the system and if there are any, how they are resolved in the system.
//
//Note: if you got all Perfect on this song, you would get (p=10)*B, which is 80,000,000. In fact, the maximum possible score for any song is the number of feet difficulty X 10,000,000.
static int iNumTimesCalled = 0;
iNumTimesCalled ++;
LOG->WriteLine("Called %d times - param %d.",iNumTimesCalled, iCurCombo);
int p; // score multiplier
switch( score )
{
case TNS_PERFECT: p = 10; break;
case TNS_GREAT: p = 5; break;
default: p = 0; break;
}
int N = m_iTotalNotes;
int n = iCurCombo+1;
int B = m_iNotesMeter * 1000000;
float S = (1+N)*N/2.0f;
int one_step_score = roundf( p * (B/S) * n );
m_fScore += one_step_score;
ASSERT( m_fScore >= 0 );
// HACK: The final total is slightly off because of rounding errors
if( fabsf(m_fScore-B*10) < 100.0f )
m_fScore = (float)B*10;
this->SetScore( m_fScore );
}
+4 -15
View File
@@ -3,7 +3,7 @@
-----------------------------------------------------------------------------
Class: ScoreDisplayOni
Desc: A graphic displayed in the ScoreDisplayOni during Dancing.
Desc: Shows time into course.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
@@ -20,23 +20,12 @@ class ScoreDisplayOni : public ScoreDisplay
public:
ScoreDisplayOni();
virtual void Init( PlayerNumber pn, PlayerOptions po, int iOriginalNumNotes, int iNotesMeter );
virtual void SetScore( float fNewScore );
virtual int GetScore();
virtual void AddToScore( TapNoteScore score, int iCurCombo );
virtual void Init( PlayerNumber pn );
virtual void Update( float fDeltaTime );
virtual void Draw();
virtual void SetScore( float fNewScore );
protected:
PlayerNumber m_PlayerNumber;
PlayerOptions m_PlayerOptions;
int m_iTotalNotes;
int m_iNotesMeter;
float m_fScore;
float m_fTrailingScore;
float m_fScoreVelocity;
};
+42 -40
View File
@@ -118,14 +118,15 @@ ScreenEdit::ScreenEdit()
m_pNotes->GetNoteData( &noteData );
m_Mode = MODE_EDIT;
m_EditMode = MODE_EDITING;
GAMESTATE->m_bEditing = true;
m_fBeat = 0.0f;
m_fTrailingBeat = m_fBeat;
GAMESTATE->m_fSongBeat = m_fBeat;
m_PlayerOptions.m_fArrowScrollSpeed = 1;
m_PlayerOptions.m_ColorType = PlayerOptions::COLOR_NOTE;
// m_PlayerOptions.m_bShowMeasureBars = true;
GAMESTATE->m_PlayerOptions[PLAYER_1].m_fArrowScrollSpeed = 1;
GAMESTATE->m_PlayerOptions[PLAYER_1].m_ColorType = PlayerOptions::COLOR_NOTE;
m_sprBackground.Load( THEME->GetPathTo( GRAPHIC_EDIT_BACKGROUND ) );
m_sprBackground.StretchTo( CRect(SCREEN_LEFT,SCREEN_TOP,SCREEN_RIGHT,SCREEN_BOTTOM) );
@@ -136,27 +137,27 @@ ScreenEdit::ScreenEdit()
m_GranularityIndicator.SetZoom( 0.5f );
m_GrayArrowRowEdit.SetXY( EDIT_X, EDIT_GRAY_Y );
m_GrayArrowRowEdit.Load( PLAYER_1, GAMESTATE->GetCurrentStyleDef(), m_PlayerOptions );
m_GrayArrowRowEdit.Load( PLAYER_1 );
m_GrayArrowRowEdit.SetZoom( 0.5f );
m_NoteFieldEdit.SetXY( EDIT_X, EDIT_GRAY_Y );
m_NoteFieldEdit.SetZoom( 0.5f );
m_NoteFieldEdit.Load( &noteData, PLAYER_1, GAMESTATE->GetCurrentStyleDef(), m_PlayerOptions, 10, 12, NoteField::MODE_EDITING );
m_NoteFieldEdit.Load( &noteData, PLAYER_1, 200, 800 );
m_rectRecordBack.StretchTo( CRect(SCREEN_LEFT, SCREEN_TOP, SCREEN_RIGHT, SCREEN_BOTTOM) );
m_rectRecordBack.SetDiffuseColor( D3DXCOLOR(0,0,0,0) );
m_GrayArrowRowRecord.SetXY( EDIT_X, EDIT_GRAY_Y );
m_GrayArrowRowRecord.Load( PLAYER_1, GAMESTATE->GetCurrentStyleDef(), m_PlayerOptions );
m_GrayArrowRowRecord.Load( PLAYER_1 );
m_GrayArrowRowRecord.SetZoom( 1.0f );
m_NoteFieldRecord.SetXY( EDIT_X, EDIT_GRAY_Y );
m_NoteFieldRecord.SetZoom( 1.0f );
m_NoteFieldRecord.Load( &noteData, PLAYER_1, GAMESTATE->GetCurrentStyleDef(), m_PlayerOptions, 2, 5, NoteField::MODE_EDITING );
m_NoteFieldRecord.Load( &noteData, PLAYER_1, 60, 300 );
m_Clipboard.m_iNumTracks = m_NoteFieldEdit.m_iNumTracks;
m_Player.Load( PLAYER_1, GAMESTATE->GetCurrentStyleDef(), &noteData, PlayerOptions(), NULL, NULL, 1, 1 );
m_Player.Load( PLAYER_1, &noteData, NULL, NULL );
m_Player.SetXY( PLAYER_X, PLAYER_Y );
m_Fade.SetClosed();
@@ -204,46 +205,46 @@ void ScreenEdit::Update( float fDeltaTime )
bool bFreeze;
m_pSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS, bFreeze );
if( m_Mode == MODE_RECORD || m_Mode == MODE_PLAY )
if( m_EditMode == MODE_RECORDING || m_EditMode == MODE_PLAYING )
{
m_fBeat = fSongBeat;
if( m_fBeat > m_NoteFieldEdit.m_fEndMarker )
{
if( m_Mode == MODE_RECORD )
if( m_EditMode == MODE_RECORDING )
{
TransitionToEditFromRecord();
}
else if( m_Mode == MODE_PLAY )
else if( m_EditMode == MODE_PLAYING )
{
m_soundMusic.Stop();
m_Mode = MODE_EDIT;
m_EditMode = MODE_EDITING;
}
}
}
m_sprBackground.Update( fDeltaTime );
m_GranularityIndicator.Update( fDeltaTime );
m_GrayArrowRowEdit.Update( fDeltaTime, m_fBeat );
m_NoteFieldEdit.Update( fDeltaTime, m_fBeat );
m_GrayArrowRowEdit.Update( fDeltaTime );
m_NoteFieldEdit.Update( fDeltaTime );
m_Fade.Update( fDeltaTime );
m_textHelp.Update( fDeltaTime );
m_textInfo.Update( fDeltaTime );
if( m_Mode == MODE_RECORD || m_Mode == MODE_PLAY )
if( m_EditMode == MODE_RECORDING || m_EditMode == MODE_PLAYING )
{
m_rectRecordBack.Update( fDeltaTime );
}
if( m_Mode == MODE_RECORD )
if( m_EditMode == MODE_RECORDING )
{
m_GrayArrowRowRecord.Update( fDeltaTime, m_fBeat );
m_NoteFieldRecord.Update( fDeltaTime, m_fBeat );
m_GrayArrowRowRecord.Update( fDeltaTime );
m_NoteFieldRecord.Update( fDeltaTime );
}
if( m_Mode == MODE_PLAY )
if( m_EditMode == MODE_PLAYING )
{
m_Player.Update( fDeltaTime, m_fBeat, 0.35f );
m_Player.Update( fDeltaTime );
}
//LOG->WriteLine( "ScreenEdit::Update(%f)", fDeltaTime );
@@ -251,11 +252,12 @@ void ScreenEdit::Update( float fDeltaTime )
// Update trailing beat
float fDelta = m_fBeat - m_fTrailingBeat;
float fDelta = m_fBeat - GAMESTATE->m_fSongBeat;
if( fabsf(fDelta) < 0.01 )
{
m_fTrailingBeat = m_fBeat; // snap
GAMESTATE->m_fSongBeat = m_fBeat; // snap
}
else
{
@@ -263,10 +265,10 @@ void ScreenEdit::Update( float fDeltaTime )
float fMoveDelta = fSign*fDeltaTime*40;
if( fabsf(fMoveDelta) > fabsf(fDelta) )
fMoveDelta = fDelta;
m_fTrailingBeat += fMoveDelta;
GAMESTATE->m_fSongBeat += fMoveDelta;
if( fabsf(fDelta) > 10 )
m_fTrailingBeat += fDelta * fDeltaTime*5;
GAMESTATE->m_fSongBeat += fDelta * fDeltaTime*5;
}
@@ -278,7 +280,7 @@ void ScreenEdit::Update( float fDeltaTime )
// LOG->WriteLine( "fPositionSeconds = %f, fSongBeat = %f, fBPS = %f", fPositionSeconds, fSongBeat, fBPS );
m_NoteFieldEdit.Update( fDeltaTime, m_fTrailingBeat );
m_NoteFieldEdit.Update( fDeltaTime );
int iIndexNow = BeatToNoteRowNotRounded( m_fBeat );
@@ -334,18 +336,18 @@ void ScreenEdit::DrawPrimitives()
m_textInfo.Draw();
m_Fade.Draw();
if( m_Mode == MODE_RECORD || m_Mode == MODE_PLAY )
if( m_EditMode == MODE_RECORDING || m_EditMode == MODE_PLAYING )
{
m_rectRecordBack.Draw();
}
if( m_Mode == MODE_RECORD )
if( m_EditMode == MODE_RECORDING )
{
m_GrayArrowRowRecord.Draw();
m_NoteFieldRecord.Draw();
}
if( m_Mode == MODE_PLAY )
if( m_EditMode == MODE_PLAYING )
{
m_Player.Draw();
}
@@ -357,11 +359,11 @@ void ScreenEdit::Input( const DeviceInput& DeviceI, const InputEventType type, c
{
//LOG->WriteLine( "ScreenEdit::Input()" );
switch( m_Mode )
switch( m_EditMode )
{
case MODE_EDIT: InputEdit( DeviceI, type, GameI, MenuI, StyleI ); break;
case MODE_RECORD: InputRecord( DeviceI, type, GameI, MenuI, StyleI ); break;
case MODE_PLAY: InputPlay( DeviceI, type, GameI, MenuI, StyleI ); break;
case MODE_EDITING: InputEdit( DeviceI, type, GameI, MenuI, StyleI ); break;
case MODE_RECORDING: InputRecord( DeviceI, type, GameI, MenuI, StyleI ); break;
case MODE_PLAYING: InputPlay( DeviceI, type, GameI, MenuI, StyleI ); break;
}
}
@@ -568,9 +570,9 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
m_fBeat = m_NoteFieldEdit.m_fBeginMarker;
m_Mode = MODE_PLAY;
m_EditMode = MODE_PLAYING;
m_Player.Load( PLAYER_1, GAMESTATE->GetCurrentStyleDef(), (NoteData*)&m_NoteFieldEdit, PlayerOptions(), NULL, NULL, 1, 1 );
m_Player.Load( PLAYER_1, (NoteData*)&m_NoteFieldEdit, NULL, NULL );
m_rectRecordBack.BeginTweening( 0.5f );
m_rectRecordBack.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0.5f) );
@@ -598,7 +600,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
m_NoteFieldRecord.m_fEndMarker = m_NoteFieldEdit.m_fEndMarker;
m_Mode = MODE_RECORD;
m_EditMode = MODE_RECORDING;
m_rectRecordBack.BeginTweening( 0.5f );
m_rectRecordBack.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0.5f) );
@@ -874,7 +876,7 @@ void ScreenEdit::InputPlay( const DeviceInput& DeviceI, const InputEventType typ
switch( DeviceI.button )
{
case DIK_ESCAPE:
m_Mode = MODE_EDIT;
m_EditMode = MODE_EDITING;
m_soundMusic.Stop();
m_fBeat = froundf( m_fBeat, NoteTypeToBeat(m_GranularityIndicator.GetSnapMode()) );
@@ -890,7 +892,7 @@ void ScreenEdit::InputPlay( const DeviceInput& DeviceI, const InputEventType typ
switch( StyleI.player )
{
case PLAYER_1:
m_Player.HandlePlayerStep( m_fBeat, StyleI.col, fMaxBeatDifference );
m_Player.Step( StyleI.col );
return;
}
@@ -899,7 +901,7 @@ void ScreenEdit::InputPlay( const DeviceInput& DeviceI, const InputEventType typ
void ScreenEdit::TransitionToEditFromRecord()
{
m_Mode = MODE_EDIT;
m_EditMode = MODE_EDITING;
m_soundMusic.Stop();
int iNoteIndexBegin = BeatToNoteRow( m_NoteFieldEdit.m_fBeginMarker );
+3 -6
View File
@@ -41,14 +41,12 @@ protected:
void OnSnapModeChange();
enum EditMode { MODE_EDIT, MODE_RECORD, MODE_PLAY };
EditMode m_Mode;
enum EditMode { MODE_EDITING, MODE_RECORDING, MODE_PLAYING };
EditMode m_EditMode;
Song* m_pSong;
Notes* m_pNotes;
PlayerOptions m_PlayerOptions;
Sprite m_sprBackground;
NoteField m_NoteFieldEdit;
@@ -59,8 +57,7 @@ protected:
BitmapText m_textHelp;
// keep track of where we are and what we're doing
float m_fTrailingBeat; // this approaches m_fBeat
float m_fBeat;
float m_fBeat; // make GAMESTATE->m_fSongBeat approach this
NoteData m_Clipboard;
+122 -85
View File
@@ -73,6 +73,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
m_ResultMode = bSummary ? RM_ARCADE_SUMMARY : RM_ARCADE_STAGE;
break;
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
m_ResultMode = RM_ONI;
break;
default:
@@ -80,65 +81,55 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
}
///////////////////////////
// Figure out which statistics we're going to display
///////////////////////////
int iPossibleDancePoints[NUM_PLAYERS];
int iActualDancePoints[NUM_PLAYERS];
int iTapNoteScores[NUM_PLAYERS][NUM_TAP_NOTE_SCORES];
int iHoldNoteScores[NUM_PLAYERS][NUM_HOLD_NOTE_SCORES];
int iMaxCombo[NUM_PLAYERS];
float fScore[NUM_PLAYERS];
float fPossibleRadarValues[NUM_PLAYERS][NUM_RADAR_CATEGORIES];
float fActualRadarValues[NUM_PLAYERS][NUM_RADAR_CATEGORIES];
///////////////////////////
// Calculate total statistics depending on m_ResultMode
///////////////////////////
GameplayStatistics totalGS;
switch( m_ResultMode )
{
case RM_ARCADE_STAGE:
{
// take the latest GameplayStatistics
totalGS = GAMESTATE->m_aGameplayStatistics[GAMESTATE->m_aGameplayStatistics.GetSize()-1];
}
break;
case RM_ARCADE_SUMMARY:
COPY( iPossibleDancePoints, GAMESTATE->m_iAccumPossibleDancePoints );
COPY( iActualDancePoints, GAMESTATE->m_iAccumActualDancePoints );
COPY( iTapNoteScores, GAMESTATE->m_AccumTapNoteScores );
COPY( iHoldNoteScores, GAMESTATE->m_AccumHoldNoteScores );
COPY( iMaxCombo, GAMESTATE->m_iAccumMaxCombo );
COPY( fScore, GAMESTATE->m_fAccumScore );
COPY( fPossibleRadarValues, GAMESTATE->m_fAccumRadarPossible );
COPY( fActualRadarValues, GAMESTATE->m_fAccumRadarActual );
break;
case RM_ARCADE_STAGE:
case RM_ONI:
{
int iFirstToTakeFrom;
switch( m_ResultMode )
{
case RM_ARCADE_SUMMARY:
iFirstToTakeFrom = max( 0, GAMESTATE->m_aGameplayStatistics.GetSize()-STAGES_TO_SHOW_IN_SUMMARY );
break;
case RM_ONI:
iFirstToTakeFrom = 0;
break;
default:
ASSERT(0);
}
for( int i=iFirstToTakeFrom; i<GAMESTATE->m_aGameplayStatistics.GetSize(); i++ )
totalGS += GAMESTATE->m_aGameplayStatistics[i];
// Chris:
// ugly... GameplayStatistics::operator+= simply sums the radar values, so we need
// to divide by the number of stages taken from to normalize the values.
int iNumTakenFrom = GAMESTATE->m_aGameplayStatistics.GetSize() - iFirstToTakeFrom;
for( int p=0; p<NUM_PLAYERS; p++ )
{
for( int r=0; r<NUM_RADAR_CATEGORIES; r++ )
{
totalGS.fRadarActual[p][r] /= iNumTakenFrom;
totalGS.fRadarPossible[p][r] /= iNumTakenFrom;
}
}
}
COPY( iPossibleDancePoints, GAMESTATE->m_iPossibleDancePoints );
COPY( iActualDancePoints, GAMESTATE->m_iActualDancePoints );
COPY( iTapNoteScores, GAMESTATE->m_TapNoteScores );
COPY( iHoldNoteScores, GAMESTATE->m_HoldNoteScores );
COPY( iMaxCombo, GAMESTATE->m_iMaxCombo );
COPY( fScore, GAMESTATE->m_fScore );
COPY( fPossibleRadarValues, GAMESTATE->m_fRadarPossible );
COPY( fActualRadarValues, GAMESTATE->m_fRadarActual );
break;
}
///////////////////////////
// Andy:
// Fake COOL! / GOOD / OOPS for Ez2dancer using the DDR Rankings.
if( GAMESTATE->m_CurGame == GAME_EZ2 )
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
totalGS.perfect[p] += totalGS.great[p];
totalGS.great[p] = 0;
totalGS.miss[p] += totalGS.boo[p];
totalGS.boo[p] = 0;
iTapNoteScores[p][TNS_PERFECT] += iTapNoteScores[p][TNS_GREAT];
iTapNoteScores[p][TNS_GREAT] = 0;
iTapNoteScores[p][TNS_MISS] += iTapNoteScores[p][TNS_BOO];
iTapNoteScores[p][TNS_BOO] = 0;
}
}
@@ -159,17 +150,16 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
// crop down to 3
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( GAMESTATE->m_aGameplayStatistics.GetSize() > STAGES_TO_SHOW_IN_SUMMARY )
GAMESTATE->m_aGameplayStatistics.RemoveAt( 0, GAMESTATE->m_aGameplayStatistics.GetSize() - STAGES_TO_SHOW_IN_SUMMARY );
if( GAMESTATE->m_apSongsPlayed.GetSize() > STAGES_TO_SHOW_IN_SUMMARY )
GAMESTATE->m_apSongsPlayed.RemoveAt( 0, GAMESTATE->m_apSongsPlayed.GetSize() - STAGES_TO_SHOW_IN_SUMMARY );
}
const int iSongsToShow = GAMESTATE->m_aGameplayStatistics.GetSize();
const int iSongsToShow = GAMESTATE->m_apSongsPlayed.GetSize();
ASSERT( iSongsToShow > 0 );
for( int i=0; i<iSongsToShow; i++ )
{
GameplayStatistics &GS = GAMESTATE->m_aGameplayStatistics[i];
m_BannerWithFrame[i].LoadFromSong( GS.pSong );
m_BannerWithFrame[i].LoadFromSong( GAMESTATE->m_apSongsPlayed[i] );
float fBannerOffset = i - (iSongsToShow-1)/2.0f;
m_BannerWithFrame[i].SetXY( BANNER_X + fBannerOffset*32, BANNER_Y + fBannerOffset*16 );
m_BannerWithFrame[i].SetZoom( 0.70f );
@@ -193,7 +183,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
m_Menu.Load(
THEME->GetPathTo(GRAPHIC_EVALUATION_BACKGROUND),
m_ResultMode==RM_ARCADE_SUMMARY ? THEME->GetPathTo(GRAPHIC_EVALUATION_SUMMARY_TOP_EDGE) : THEME->GetPathTo(GRAPHIC_EVALUATION_TOP_EDGE),
"Press START to continue.",
"Press START to continue",
false, true, 40
);
this->AddSubActor( &m_Menu );
@@ -257,6 +247,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
if (GAMESTATE->m_CurGame != GAME_EZ2)
{
m_sprScoreLabel.Load( THEME->GetPathTo(GRAPHIC_EVALUATION_SCORE_LABELS) );
m_sprScoreLabel.SetState( m_ResultMode==RM_ONI ? 1 : 0 );
m_sprScoreLabel.StopAnimating();
m_sprScoreLabel.SetXY( SCORE_LABEL_X, SCORE_Y );
m_sprScoreLabel.SetZoom( 1.0f );
@@ -280,14 +271,38 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
// Calculate grades
//
Grade grade[NUM_PLAYERS];
Grade max_grade = GRADE_NO_DATA;
for( p=0; p<NUM_PLAYERS; p++ )
{
PlayerNumber pn = (PlayerNumber)p;
grade[p] = !GAMESTATE->IsPlayerEnabled(pn) ? GRADE_NO_DATA : totalGS.GetGrade(pn);
max_grade = max( max_grade, grade[p] );
if( !GAMESTATE->IsPlayerEnabled(p) || GAMESTATE->m_bUsedAutoPlayer || GAMESTATE->m_fSecondsBeforeFail[p] != -1 )
{
grade[p] = GRADE_E;
}
else
{
//Based on the percentage of your total "Dance Points" to the maximum possible number, the following rank is assigned:
//
//100% - AAA
//93 % - AA
//80 % - A
//65 % - B
//45 % - C
//Less - D
//Fail - E
float fPercentDancePoints = iActualDancePoints[p] / (float)iPossibleDancePoints[p];
if ( fPercentDancePoints >= 1.00 ) grade[p] = GRADE_AAA;
else if( fPercentDancePoints >= 0.93 ) grade[p] = GRADE_AA;
else if( fPercentDancePoints >= 0.80 ) grade[p] = GRADE_A;
else if( fPercentDancePoints >= 0.65 ) grade[p] = GRADE_B;
else if( fPercentDancePoints >= 0.45 ) grade[p] = GRADE_C;
else grade[p] = GRADE_D;
}
}
Grade max_grade = GRADE_NO_DATA;
for( p=0; p<NUM_PLAYERS; p++ )
max_grade = max( max_grade, grade[p] );
//////////////////////////
// Set Numbers
@@ -297,45 +312,59 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
continue; // skip
m_textJudgeNumbers[0][p].SetText( ssprintf("%4d", totalGS.perfect[p]) );
m_textJudgeNumbers[1][p].SetText( ssprintf("%4d", totalGS.great[p]) );
m_textJudgeNumbers[2][p].SetText( ssprintf("%4d", totalGS.good[p]) );
m_textJudgeNumbers[3][p].SetText( ssprintf("%4d", totalGS.boo[p]) );
m_textJudgeNumbers[4][p].SetText( ssprintf("%4d", totalGS.miss[p]) );
m_textJudgeNumbers[5][p].SetText( ssprintf("%4d", totalGS.ok[p]) );
m_textJudgeNumbers[0][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_PERFECT]) );
m_textJudgeNumbers[1][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_GREAT]) );
m_textJudgeNumbers[2][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_GOOD]) );
m_textJudgeNumbers[3][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_BOO]) );
m_textJudgeNumbers[4][p].SetText( ssprintf("%4d", iTapNoteScores[p][TNS_MISS]) );
m_textJudgeNumbers[5][p].SetText( ssprintf("%4d", iHoldNoteScores[p][HNS_OK]) );
m_ScoreDisplay[p].SetScore( (float)totalGS.max_combo[p] * 1000 );
m_ScoreDisplay[p].SetScore( (float)totalGS.score[p] );
if( m_ResultMode==RM_ONI )
{
const float fSurviveSeconds = GAMESTATE->GetPlayerSurviveTime( (PlayerNumber)p );
int iMinsDisplay = (int)fSurviveSeconds/60;
int iSecsDisplay = (int)fSurviveSeconds - iMinsDisplay*60;
int iLeftoverDisplay = int( (fSurviveSeconds - iMinsDisplay*60 - iSecsDisplay) * 100 );
m_ScoreDisplay[p].SetText( ssprintf( "%02d:%02d:%02d", iMinsDisplay, iSecsDisplay, iLeftoverDisplay ) );
}
else
{
m_ScoreDisplay[p].SetScore( fScore[p] );
}
// SNEAKY! We take the max combo, and put it into element 5, because Ez2dancer
// doesn't care for OK's and plus this text element is already nicely aligned =)
if (GAMESTATE->m_CurGame == GAME_EZ2)
{
m_textJudgeNumbers[5][p].SetText( ssprintf("%4d", totalGS.max_combo[p]) );
m_textJudgeNumbers[5][p].SetText( ssprintf("%4d", iMaxCombo[p]) );
}
m_ScoreDisplay[p].SetScore( (float)totalGS.max_combo[p] * 1000 );
m_ScoreDisplay[p].SetScore( (float)totalGS.score[p] );
m_BonusInfoFrame[p].SetBonusInfo( (PlayerNumber)p, fPossibleRadarValues[p], fActualRadarValues[p], iMaxCombo[p] );
m_StageBox[p].SetStageInfo( (PlayerNumber)p, GAMESTATE->m_iStagesIntoCourse[p] );
}
m_BonusInfoFrame[p].SetBonusInfo( (PlayerNumber)p, totalGS.fRadarPossible[p], totalGS.fRadarActual[p], totalGS.max_combo[p] );
////////////////////////
// update persistent statistics
////////////////////////
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(p) )
continue;
switch( m_ResultMode )
{
case RM_ARCADE_STAGE:
////////////////////////
// update song stats
////////////////////////
Notes* pNotes = GAMESTATE->m_pCurNotes[p];
pNotes->m_iNumTimesPlayed++;
if( totalGS.max_combo[p] > pNotes->m_iMaxCombo )
pNotes->m_iMaxCombo = totalGS.max_combo[p];
if( iMaxCombo[p] > pNotes->m_iMaxCombo )
pNotes->m_iMaxCombo = iMaxCombo[p];
if( totalGS.score[p] > pNotes->m_iTopScore )
if( fScore[p] > pNotes->m_iTopScore )
{
pNotes->m_iTopScore = (int)totalGS.score[p];
pNotes->m_iTopScore = (int)fScore[p];
m_bNewRecord[p] = true;
}
@@ -390,13 +419,12 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
m_textOniPercent[p].SetZoomY( 2.5f );
m_textOniPercent[p].SetEffectGlowing( 1.0f );
int iActualDancePoints = 0;
for( int i=0; i<GAMESTATE->m_aGameplayStatistics.GetSize(); i++ )
iActualDancePoints += GAMESTATE->m_aGameplayStatistics[i].iActualDancePoints[p];
int iPossibleDancePoints = GAMESTATE->m_iCoursePossibleDancePoints;
float fPercentDancePoints = iActualDancePoints / (float)iPossibleDancePoints + 0.0001f; // correct for rounding errors
float fPercentDancePoints = iActualDancePoints[p] / (float)iPossibleDancePoints[p] + 0.0001f; // correct for rounding errors
m_textOniPercent[p].SetText( ssprintf("%.1f%%", fPercentDancePoints*100) );
this->AddSubActor( &m_textOniPercent[p] );
m_StageBox[p].SetXY( BONUS_FRAME_X[p], BONUS_FRAME_Y );
this->AddSubActor( &m_StageBox[p] );
}
break;
case RM_ARCADE_STAGE:
@@ -408,6 +436,9 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
m_Grades[p].SetZoom( 1.0f );
m_Grades[p].SetEffectGlowing( 1.0f );
m_Grades[p].SpinAndSettleOn( grade[p] );
m_BonusInfoFrame[p].SetXY( BONUS_FRAME_X[p], BONUS_FRAME_Y );
this->AddSubActor( &m_BonusInfoFrame[p] );
}
else // Ez2dancer Style Grade Display.
{
@@ -433,9 +464,6 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
if ( GAMESTATE->m_CurGame == GAME_EZ2)
continue;
m_BonusInfoFrame[p].SetXY( BONUS_FRAME_X[p], BONUS_FRAME_Y );
this->AddSubActor( &m_BonusInfoFrame[p] );
m_bNewRecord[p] = false;
if( m_bNewRecord[p] )
@@ -574,6 +602,12 @@ void ScreenEvaluation::TweenOnScreen()
m_BonusInfoFrame[p].BeginTweeningQueued( MENU_ELEMENTS_TWEEN_TIME, Actor::TWEEN_BIAS_BEGIN );
m_BonusInfoFrame[p].SetTweenX( fOriginalX );
fOriginalX = m_StageBox[p].GetX();
m_StageBox[p].SetX( fOriginalX + SCREEN_WIDTH/2*(p==PLAYER_1 ? 1 : -1) );
m_StageBox[p].BeginTweeningQueued( 0.2f + 0.1f*i );
m_StageBox[p].BeginTweeningQueued( MENU_ELEMENTS_TWEEN_TIME, Actor::TWEEN_BIAS_BEGIN );
m_StageBox[p].SetTweenX( fOriginalX );
m_sprGradeFrame[p].BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_sprGradeFrame[p].SetTweenZoomY( 0 );
@@ -634,6 +668,9 @@ void ScreenEvaluation::TweenOffScreen()
m_BonusInfoFrame[p].BeginTweeningQueued( MENU_ELEMENTS_TWEEN_TIME, Actor::TWEEN_BIAS_END );
m_BonusInfoFrame[p].SetTweenZoomY( 0 );
m_StageBox[p].BeginTweeningQueued( MENU_ELEMENTS_TWEEN_TIME, Actor::TWEEN_BIAS_END );
m_StageBox[p].SetTweenZoomY( 0 );
m_sprGradeFrame[p].BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_sprGradeFrame[p].SetTweenZoomY( 0 );
@@ -704,7 +741,7 @@ void ScreenEvaluation::MenuStart( const PlayerNumber p )
if( PREFSMAN->m_bEventMode )
{
GAMESTATE->m_iCurrentStageIndex++;
// GAMESTATE->m_iCurrentStageIndex++;
m_Menu.TweenOffScreenToMenu( SM_GoToSelectMusic );
return;
}
@@ -717,7 +754,7 @@ void ScreenEvaluation::MenuStart( const PlayerNumber p )
case RM_ARCADE_STAGE:
if( m_bTryExtraStage )
{
GAMESTATE->m_iCurrentStageIndex++;
// GAMESTATE->m_iCurrentStageIndex++;
m_Menu.TweenOffScreenToMenu( SM_GoToSelectMusic );
}
else if(
@@ -729,7 +766,7 @@ void ScreenEvaluation::MenuStart( const PlayerNumber p )
}
else
{
GAMESTATE->m_iCurrentStageIndex++;
// GAMESTATE->m_iCurrentStageIndex++;
m_Menu.TweenOffScreenToMenu( SM_GoToSelectMusic );
}
+3 -1
View File
@@ -19,6 +19,7 @@
#include "Banner.h"
#include "ScoreDisplayNormal.h"
#include "BonusInfoFrame.h"
#include "StageBox.h"
#include "BannerWithFrame.h"
@@ -51,7 +52,8 @@ protected:
GradeDisplay m_Grades[NUM_PLAYERS];
BitmapText m_textOniPercent[NUM_PLAYERS];
BonusInfoFrame m_BonusInfoFrame[NUM_PLAYERS];
BonusInfoFrame m_BonusInfoFrame[NUM_PLAYERS]; // used in arcade
StageBox m_StageBox[NUM_PLAYERS]; // used in Oni
Sprite m_sprJudgeLabels[NUM_JUDGE_LINES];
BitmapText m_textJudgeNumbers[NUM_JUDGE_LINES][NUM_PLAYERS];
+208 -125
View File
@@ -83,42 +83,51 @@ ScreenGameplay::ScreenGameplay()
{
LOG->WriteLine( "ScreenGameplay::ScreenGameplay()" );
m_bAutoPlayerWasOn = PREFSMAN->m_bAutoPlay;
m_bChangedOffsetOrBPM = false;
switch( GAMESTATE->m_PlayMode )
GAMESTATE->ResetStageStatistics(); // clear values
// Update possible dance points
for( int p=0; p<NUM_PLAYERS; p++ )
{
case PLAY_MODE_ARCADE:
if( !GAMESTATE->IsPlayerEnabled(p) )
continue; // skip
NoteData notedata;
switch( GAMESTATE->m_PlayMode )
{
m_apSongQueue.Add( GAMESTATE->m_pCurSong );
for( int p=0; p<NUM_PLAYERS; p++ )
m_apNotesQueue[p].Add( GAMESTATE->m_pCurNotes[p] );
}
break;
case PLAY_MODE_ONI:
{
Course* pCourse = GAMESTATE->m_pCurCourse;
ASSERT( pCourse != NULL );
m_apSongQueue.RemoveAll();
for( int p=0; p<NUM_PLAYERS; p++ )
m_apNotesQueue[p].RemoveAll();
pCourse->GetSongAndNotesForCurrentStyle( m_apSongQueue, m_apNotesQueue );
// store possible dance points in GAMESTATE
GAMESTATE->m_iCoursePossibleDancePoints = 0;
for( int i=0; i<m_apNotesQueue[PLAYER_1].GetSize(); i++ )
case PLAY_MODE_ARCADE:
GAMESTATE->m_pCurNotes[p]->GetNoteData( &notedata );
GAMESTATE->m_iPossibleDancePoints[p] = notedata.GetPossibleDancePoints();
break;
case PLAY_MODE_ENDLESS:
GAMESTATE->m_iPossibleDancePoints[p] = -1;
break;
case PLAY_MODE_ONI:
{
NoteData nd;
m_apNotesQueue[PLAYER_1][i]->GetNoteData( &nd );
GAMESTATE->m_iCoursePossibleDancePoints += nd.GetPossibleDancePoints();
GAMESTATE->m_iPossibleDancePoints[p] = 0;
Course* pCourse = GAMESTATE->m_pCurCourse;
CArray<Song*,Song*> apSongs;
CArray<Notes*,Notes*> apNotes[NUM_PLAYERS];
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes );
for( int i=0; i<apNotes[p].GetSize(); i++ )
{
apNotes[p][i]->GetNoteData( &notedata );
int iPossibleDancePoints = notedata.GetPossibleDancePoints();
GAMESTATE->m_iPossibleDancePoints[p] += iPossibleDancePoints;
}
}
break;
}
break;
}
GAMESTATE->m_bUsedAutoPlayer &= PREFSMAN->m_bAutoPlay;
m_bChangedOffsetOrBPM = false;
m_DancingState = STATE_INTRO;
m_fTimeLeftBeforeDancingComment = TIME_BETWEEN_DANCING_COMMENTS;
@@ -128,7 +137,7 @@ ScreenGameplay::ScreenGameplay()
for( int p=0; p<NUM_PLAYERS; p++ )
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
continue;
@@ -145,19 +154,19 @@ ScreenGameplay::ScreenGameplay()
for( p=0; p<NUM_PLAYERS; p++ )
{
switch( GAMESTATE->m_PlayMode )
switch( GAMESTATE->m_SongOptions.m_LifeType )
{
case PLAY_MODE_ARCADE:
case SongOptions::LIFE_BAR:
m_pLifeMeter[p] = new LifeMeterBar;
break;
case PLAY_MODE_ONI:
case SongOptions::LIFE_BATTERY:
m_pLifeMeter[p] = new LifeMeterBattery;
break;
default:
ASSERT(0);
}
m_pLifeMeter[p]->Load( (PlayerNumber)p, GAMESTATE->m_PlayerOptions[p] );
m_pLifeMeter[p]->Load( (PlayerNumber)p );
m_pLifeMeter[p]->SetXY( LIFE_LOCAL_X[p], LIFE_LOCAL_Y[p] );
m_frameTop.AddSubActor( m_pLifeMeter[p] );
@@ -220,6 +229,7 @@ ScreenGameplay::ScreenGameplay()
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
case PLAY_MODE_ENDLESS:
m_pScoreDisplay[p] = new ScoreDisplayNormal;
break;
case PLAY_MODE_ONI:
@@ -229,7 +239,7 @@ ScreenGameplay::ScreenGameplay()
ASSERT(0);
}
m_pScoreDisplay[p]->Init( (PlayerNumber)p, GAMESTATE->m_PlayerOptions[p], 100, 7 );
m_pScoreDisplay[p]->Init( (PlayerNumber)p );
m_pScoreDisplay[p]->SetXY( SCORE_LOCAL_X[p], SCORE_LOCAL_Y[p] );
m_pScoreDisplay[p]->SetZoom( 0.8f );
m_pScoreDisplay[p]->SetDiffuseColor( PlayerToColor(p) );
@@ -350,7 +360,7 @@ ScreenGameplay::ScreenGameplay()
m_soundAssistTick.Load( THEME->GetPathTo(SOUND_GAMEPLAY_ASSIST_TICK) );
LoadNextSong( false );
LoadNextSong( true );
// Send some messages every have second to we can get the introduction rolling
for( int i=0; i<30; i++ )
@@ -370,37 +380,62 @@ ScreenGameplay::~ScreenGameplay()
m_soundMusic.Stop();
}
void ScreenGameplay::LoadNextSong( bool bPlayMusic )
bool ScreenGameplay::IsLastSong()
{
if( m_apSongQueue.GetSize() == 0 )
switch( GAMESTATE->m_PlayMode )
{
this->SendScreenMessage( SM_LastNotesEnded, 0 );
return;
case PLAY_MODE_ARCADE:
return true;
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{
Course* pCourse = GAMESTATE->m_pCurCourse;
CArray<Song*,Song*> apSongs;
CArray<Notes*,Notes*> apNotes[NUM_PLAYERS];
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes );
return GAMESTATE->m_iCurrentStageIndex >= apSongs.GetSize(); // there are no more songs left
}
break;
default:
ASSERT(0);
return true;
}
}
void ScreenGameplay::LoadNextSong( bool bFirstLoad )
{
GAMESTATE->ResetMusicStatistics();
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
break;
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{
Course* pCourse = GAMESTATE->m_pCurCourse;
CArray<Song*,Song*> apSongs;
CArray<Notes*,Notes*> apNotes[NUM_PLAYERS];
pCourse->GetSongAndNotesForCurrentStyle( apSongs, apNotes );
GAMESTATE->m_pCurSong = apSongs[GAMESTATE->m_iCurrentStageIndex];
for( int p=0; p<NUM_PLAYERS; p++ )
GAMESTATE->m_pCurNotes[p] = apNotes[p][GAMESTATE->m_iCurrentStageIndex];
}
break;
default:
ASSERT(0);
break;
}
m_textStageNumber.SetText( GAMESTATE->GetStageText() );
int p;
// add a new GameplayStatistic for this song
GAMESTATE->m_aGameplayStatistics.Add( GameplayStatistics() );
GAMESTATE->m_pCurSong = m_apSongQueue[0];
m_apSongQueue.RemoveAt(0);
for( p=0; p<NUM_PLAYERS; p++ )
for( int p=0; p<NUM_PLAYERS; p++ )
{
GAMESTATE->m_pCurNotes[p] = m_apNotesQueue[p][0];
m_apNotesQueue[p].RemoveAt(0);
}
// Get the current StyleDef definition (used below)
StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
for( p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
if( !GAMESTATE->IsPlayerEnabled(p) )
continue;
m_DifficultyBanner[p].SetFromNotes( PlayerNumber(p), GAMESTATE->m_pCurNotes[p] );
@@ -409,27 +444,11 @@ void ScreenGameplay::LoadNextSong( bool bPlayMusic )
NoteData originalNoteData;
GAMESTATE->m_pCurNotes[p]->GetNoteData( &originalNoteData );
StyleDef* pStyleDef = GAMESTATE->GetCurrentStyleDef();
NoteData newNoteData;
pStyleDef->GetTransformedNoteDataForStyle( (PlayerNumber)p, &originalNoteData, &newNoteData );
// Fill in info about these notes in the latest GameplayStatistics
GAMESTATE->GetLatestGameplayStatistics().dc[p] = GAMESTATE->m_pCurNotes[p]->m_DifficultyClass;
GAMESTATE->GetLatestGameplayStatistics().meter[p] = GAMESTATE->m_pCurNotes[p]->m_iMeter;
GAMESTATE->GetLatestGameplayStatistics().iPossibleDancePoints[p] = newNoteData.GetPossibleDancePoints();
for( int r=0; r<NUM_RADAR_VALUES; r++ )
GAMESTATE->GetLatestGameplayStatistics().fRadarPossible[p][r] = newNoteData.GetRadarValue( (RadarCategory)r, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
m_Player[p].Load(
(PlayerNumber)p,
GAMESTATE->GetCurrentStyleDef(),
&newNoteData,
GAMESTATE->m_PlayerOptions[p],
m_pLifeMeter[p],
m_pScoreDisplay[p],
originalNoteData.GetNumTapNotes(),
GAMESTATE->m_pCurNotes[p]->m_iMeter
);
m_Player[p].Load( (PlayerNumber)p, &newNoteData, m_pLifeMeter[p], m_pScoreDisplay[p] );
}
@@ -442,13 +461,8 @@ void ScreenGameplay::LoadNextSong( bool bPlayMusic )
float fStartSeconds = min( 0, -4+GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat(GAMESTATE->m_pCurSong->m_fFirstBeat) );
m_soundMusic.SetPositionSeconds( fStartSeconds );
m_soundMusic.SetPlaybackRate( GAMESTATE->m_SongOptions.m_fMusicRate );
if( bPlayMusic )
if( !bFirstLoad )
m_soundMusic.Play();
if( bPlayMusic )
for( int p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
m_pLifeMeter[p]->NextSong( NULL );
}
bool ScreenGameplay::OneIsHot()
@@ -507,30 +521,15 @@ void ScreenGameplay::Update( float fDeltaTime )
// update the global music statistics for other classes to access
GAMESTATE->m_fMusicSeconds = fPositionSeconds;
GAMESTATE->m_fMusicBeat = fSongBeat;
GAMESTATE->m_fSongBeat = fSongBeat;
GAMESTATE->m_fCurBPS = fBPS;
GAMESTATE->m_bFreeze = bFreeze;
m_Background.SetSongBeat( fSongBeat, bFreeze, fPositionSeconds );
//LOG->WriteLine( "m_fOffsetInBeats = %f, m_fBeatsPerSecond = %f, m_Music.GetPositionSeconds = %f", m_fOffsetInBeats, m_fBeatsPerSecond, m_Music.GetPositionSeconds() );
const float fMaxBeatDifference = fBPS * PREFSMAN->m_fJudgeWindow * GAMESTATE->m_SongOptions.m_fMusicRate;
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
continue;
m_Player[p].Update( fDeltaTime, fSongBeat, fMaxBeatDifference );
}
// update seconds into play
for( p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled((PlayerNumber)p) && !m_pLifeMeter[p]->FailedEarlier() )
GAMESTATE->GetLatestGameplayStatistics().fSecsIntoPlay[p] = max( GAMESTATE->GetLatestGameplayStatistics().fSecsIntoPlay[p], GAMESTATE->m_fMusicSeconds );
switch( m_DancingState )
{
@@ -586,16 +585,16 @@ void ScreenGameplay::Update( float fDeltaTime )
// Send crossed row messages to Player
//
int iRowNow = BeatToNoteRowNotRounded( fSongBeat );
CLAMP( iRowNow, 0, MAX_TAP_NOTE_ROWS-1 );
static int iRowLastCrossed = 0;
CLAMP( iRowLastCrossed, 0, MAX_TAP_NOTE_ROWS-1 );
for( int r=iRowLastCrossed+1; r<=iRowNow; r++ ) // for each index we crossed since the last update
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
continue; // skip
m_Player[p].CrossedRow( r, fSongBeat, fMaxBeatDifference );
if( GAMESTATE->IsPlayerEnabled(p) )
m_Player[p].CrossedRow( r );
}
}
@@ -626,7 +625,7 @@ void ScreenGameplay::Update( float fDeltaTime )
if( !GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
continue; // skip
m_Player[p].CrossedRow( r, fSongBeat, fMaxBeatDifference );
m_Player[p].CrossedRow( r );
bAnyoneHasANote |= m_Player[p].IsThereANoteAtRow( r );
break; // this will only play the tick for the first player that is joined
}
@@ -663,7 +662,7 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
{
case DIK_F8:
PREFSMAN->m_bAutoPlay = !PREFSMAN->m_bAutoPlay;
m_bAutoPlayerWasOn &= PREFSMAN->m_bAutoPlay;
GAMESTATE->m_bUsedAutoPlayer &= PREFSMAN->m_bAutoPlay;
m_textDebug.SetText( ssprintf("Autoplayer %s.", (PREFSMAN->m_bAutoPlay ? "ON" : "OFF")) );
m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
m_textDebug.StopTweening();
@@ -725,8 +724,13 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
}
}
if( MenuI.IsValid() && MenuI.button == MENU_BUTTON_BACK && type == IET_SLOW_REPEAT )
if( MenuI.IsValid() &&
MenuI.button == MENU_BUTTON_BACK &&
type == IET_SLOW_REPEAT &&
m_DancingState != STATE_OUTRO &&
!m_Fade.IsClosing() )
{
SOUND->PlayOnceStreamed( THEME->GetPathTo(SOUND_MENU_BACK) );
m_soundMusic.Stop();
this->ClearMessageQueue();
m_Fade.CloseWipingLeft( SM_GoToScreenAfterBack );
@@ -744,7 +748,7 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
if( StyleI.IsValid() )
{
if( GAMESTATE->IsPlayerEnabled( StyleI.player ) )
m_Player[StyleI.player].HandlePlayerStep( fSongBeat, StyleI.col, fMaxBeatDifference );
m_Player[StyleI.player].Step( StyleI.col );
}
}
}
@@ -752,16 +756,75 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
void SaveChanges( void* pContext )
{
GAMESTATE->m_pCurSong->SaveToSMFile();
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
GAMESTATE->m_pCurSong->SaveToSMFile();
break;
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{
for( int i=0; i<GAMESTATE->m_pCurCourse->m_iStages; i++ )
{
Song* pSong = GAMESTATE->m_pCurCourse->m_apSongs[i];
pSong->SaveToSMFile();
}
}
break;
default:
ASSERT(0);
}
}
void DontSaveChanges( void* pContext )
{
GAMESTATE->m_pCurSong->LoadFromSMFile( GAMESTATE->m_pCurSong->GetCacheFilePath() );
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
GAMESTATE->m_pCurSong->LoadFromSMFile( GAMESTATE->m_pCurSong->GetCacheFilePath() );
break;
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
{
for( int i=0; i<GAMESTATE->m_pCurCourse->m_iStages; i++ )
{
Song* pSong = GAMESTATE->m_pCurCourse->m_apSongs[i];
pSong->LoadFromSMFile( GAMESTATE->m_pCurSong->GetCacheFilePath() );
}
}
break;
default:
ASSERT(0);
}
}
void ShowSavePrompt( ScreenMessage SM_SendWhenDone )
{
CString sMessage;
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_ARCADE:
sMessage = ssprintf(
"You have changed the offset or BPM of\n"
"%s.\n"
"Would you like to save these changes back\n"
"to the song file?\n"
"Choosing NO will disgard your changes.",
GAMESTATE->m_pCurSong->GetFullTitle() );
break;
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
sMessage = ssprintf(
"You have changed the offset or BPM of\n"
"one or more songs in this course.\n"
"Would you like to save these changes back\n"
"to the song file(s)?\n"
"Choosing NO will disgard your changes." );
break;
default:
ASSERT(0);
}
SCREENMAN->AddScreenToTop( new ScreenPrompt(
SM_SendWhenDone,
ssprintf(
@@ -820,28 +883,48 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
// received while STATE_DANCING
case SM_NotesEnded:
{
// save any statistics
for( int p=0; p<NUM_PLAYERS; p++ )
if( GAMESTATE->IsPlayerEnabled( (PlayerNumber)p ) )
m_Player[p].SaveGameplayStatistics();
GAMESTATE->GetLatestGameplayStatistics().bAutoPlayerWasOn = m_bAutoPlayerWasOn;
LoadNextSong( true );
}
break;
case SM_LastNotesEnded:
{
if( m_DancingState == STATE_OUTRO ) // gameplay already ended
return; // ignore
m_DancingState = STATE_OUTRO;
if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_END_OF_SONG && AllFailedEarlier() )
{
this->SendScreenMessage( SM_BeginFailed, 0 );
if( GAMESTATE->IsPlayerEnabled(p) )
{
m_pLifeMeter[p]->SongEnded(); // let the oni life meter give them back a life
for( int r=0; r<NUM_RADAR_CATEGORIES; r++ )
{
RadarCategory rc = (RadarCategory)r;
GAMESTATE->m_fRadarPossible[p][r] = m_Player[p].GetRadarValue( rc, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
GAMESTATE->m_fRadarActual[p][r] = m_Player[p].GetActualRadarValue( rc, GAMESTATE->m_pCurSong->m_fMusicLengthSeconds );
}
}
}
else
GAMESTATE->m_apSongsPlayed.Add( GAMESTATE->m_pCurSong );
GAMESTATE->m_iCurrentStageIndex++;
if( !IsLastSong() )
{
m_StarWipe.CloseWipingRight( SM_ShowCleared );
m_announcerCleared.PlayRandom(); // crowd cheer
LoadNextSong( false );
}
else // IsLastSong
{
if( m_DancingState == STATE_OUTRO ) // gameplay already ended
return; // ignore
m_DancingState = STATE_OUTRO;
GAMESTATE->AccumulateStageStatistics(); // accumulate values for final evaluation
if( GAMESTATE->m_SongOptions.m_FailType == SongOptions::FAIL_END_OF_SONG && AllFailedEarlier() )
{
this->SendScreenMessage( SM_BeginFailed, 0 );
}
else
{
m_StarWipe.CloseWipingRight( SM_ShowCleared );
m_announcerCleared.PlayRandom(); // crowd cheer
}
}
}
break;
+2 -5
View File
@@ -56,7 +56,8 @@ private:
void TweenOnScreen();
void TweenOffScreen();
void LoadNextSong( bool bPlayMusic );
bool IsLastSong();
void LoadNextSong( bool bFirstLoad );
bool OneIsHot();
bool AllAreInDanger();
@@ -70,12 +71,8 @@ private:
NUM_DANCING_STATES
};
DancingState m_DancingState;
bool m_bAutoPlayerWasOn;
bool m_bChangedOffsetOrBPM;
CArray<Song*,Song*> m_apSongQueue; // nearest songs are on back of queue
CArray<Notes*,Notes*> m_apNotesQueue[NUM_PLAYERS]; // nearest notes are on back of queue
float m_fTimeLeftBeforeDancingComment; // this counter is only running while STATE_DANCING
+1 -2
View File
@@ -114,8 +114,7 @@ const CString CREDIT_LINES[] =
"",
"",
"",
"Please, join the StepMania team and help us out!"
" -Chris"
"Please, join the StepMania team and help us out!",
};
const int NUM_CREDIT_LINES = sizeof(CREDIT_LINES) / sizeof(CString);
+8 -1
View File
@@ -151,6 +151,9 @@ void ScreenSelectCourse::Input( const DeviceInput& DeviceI, const InputEventType
return;
}
if( m_bMadeChoice )
return;
Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler
}
@@ -235,7 +238,11 @@ void ScreenSelectCourse::MenuStart( const PlayerNumber p )
m_Menu.TweenOffScreenToBlack( SM_None, false );
GAMESTATE->m_pCurCourse = m_MusicWheel.GetSelectedCourse();
Course* pCourse = m_MusicWheel.GetSelectedCourse();
GAMESTATE->m_pCurCourse = pCourse;
for( int p=0; p<NUM_PLAYERS; p++ )
pCourse->GetPlayerOptions( &GAMESTATE->m_PlayerOptions[p] );
pCourse->GetSongOptions( &GAMESTATE->m_SongOptions );
this->SendScreenMessage( SM_GoToNextState, 2.5f );
+13 -1
View File
@@ -63,9 +63,10 @@ const float DIFFICULTY_ARROW_X[NUM_DIFFICULTY_ITEMS][NUM_PLAYERS] = {
};
const float ARROW_SHADOW_OFFSET = 10;
const float LOCK_INPUT_TIME = 0.75f; // lock input while waiting for tweening to complete
const ScreenMessage SM_GoToPrevState = ScreenMessage(SM_User + 1);
const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User + 2);
@@ -176,6 +177,8 @@ ScreenSelectDifficulty::ScreenSelectDifficulty()
m_Menu.TweenOnScreenFromMenu( SM_None );
TweenOnScreen();
m_fLockInputTime = LOCK_INPUT_TIME;
}
@@ -193,9 +196,18 @@ void ScreenSelectDifficulty::Input( const DeviceInput& DeviceI, const InputEvent
if( m_Menu.IsClosing() )
return;
if( m_fLockInputTime > 0 )
return;
Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler
}
void ScreenSelectDifficulty::Update( float fDeltaTime )
{
Screen::Update( fDeltaTime );
m_fLockInputTime = max( m_fLockInputTime-fDeltaTime, 0 );
}
void ScreenSelectDifficulty::DrawPrimitives()
{
m_Menu.DrawBottomLayer();
+3
View File
@@ -26,6 +26,7 @@ public:
ScreenSelectDifficulty();
virtual ~ScreenSelectDifficulty();
virtual void Update( float fDeltaTime );
virtual void DrawPrimitives();
virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI );
virtual void HandleScreenMessage( const ScreenMessage SM );
@@ -64,6 +65,8 @@ private:
int m_iSelection[NUM_PLAYERS];
bool m_bChosen[NUM_PLAYERS];
float m_fLockInputTime;
};
+4
View File
@@ -338,6 +338,8 @@ void ScreenSelectMusic::MenuLeft( const PlayerNumber p, const InputEventType typ
if( type >= IET_SLOW_REPEAT && INPUTMAPPER->IsButtonDown( MenuInput(p, MENU_BUTTON_RIGHT) ) )
return; // ignore
MUSIC->Stop();
m_MusicWheel.PrevMusic();
}
@@ -347,6 +349,8 @@ void ScreenSelectMusic::MenuRight( const PlayerNumber p, const InputEventType ty
if( type >= IET_SLOW_REPEAT && INPUTMAPPER->IsButtonDown( MenuInput(p, MENU_BUTTON_LEFT) ) )
return; // ignore
MUSIC->Stop();
m_MusicWheel.NextMusic();
}
+2
View File
@@ -34,6 +34,8 @@ const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User + 3);
ScreenStage::ScreenStage()
{
MUSIC->Stop();
m_pNextScreen = NULL;
m_textStage.Load( THEME->GetPathTo(FONT_STAGE) );
-1
View File
@@ -14,7 +14,6 @@
#include "Song.h"
#include "Course.h"
#include "GameplayStatistics.h"
//#include <d3dxmath.h> // for D3DXCOLOR
const int MAX_SONG_QUEUE_SIZE = 400; // this has to be gigantic to fit an "endless" number of songs
+3 -2
View File
@@ -14,7 +14,7 @@
struct SongOptions
{
enum LifeType { LIFE_BAR_NORMAL=0, LIFE_BATTERY };
enum LifeType { LIFE_BAR=0, LIFE_BATTERY };
LifeType m_LifeType;
enum DrainType { DRAIN_NORMAL, DRAIN_NO_RECOVER, DRAIN_SUDDEN_DEATH };
DrainType m_DrainType; // only used with LifeBar
@@ -26,7 +26,8 @@ struct SongOptions
float m_fMusicRate;
SongOptions() {
m_LifeType = LIFE_BAR_NORMAL;
m_LifeType = LIFE_BAR;
m_DrainType = DRAIN_NORMAL;
m_iBatteryLives = 4;
m_FailType = FAIL_ARCADE;
m_AssistType = ASSIST_NONE;
+55
View File
@@ -0,0 +1,55 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: StageBox
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "StageBox.h"
#include "RageUtil.h"
#include "GameConstantsAndTypes.h"
#include "PrefsManager.h"
#include "RageLog.h"
const float NUMBER_X = 16;
const float NUMBER_Y = 24;
const float ST_X = NUMBER_X+4;
const float ST_Y = NUMBER_Y;
StageBox::StageBox()
{
this->AddSubActor( &m_sprBox );
m_textNumber.Load( THEME->GetPathTo(FONT_HEADER1) );
m_textNumber.TurnShadowOff();
m_textNumber.SetHorizAlign( Actor::align_right );
m_textNumber.SetVertAlign( Actor::align_top );
m_textNumber.SetZoom( 2.0f );
m_textNumber.SetXY( NUMBER_X, NUMBER_Y );
this->AddSubActor( &m_textNumber );
m_textST.Load( THEME->GetPathTo(FONT_HEADER1) );
m_textST.TurnShadowOff();
m_textST.SetHorizAlign( Actor::align_left );
m_textST.SetVertAlign( Actor::align_top );
m_textST.SetZoom( 1 );
m_textST.SetXY( ST_X, ST_Y );
this->AddSubActor( &m_textST );
}
void StageBox::SetStageInfo( PlayerNumber p, int iNumStagesCompleted )
{
m_sprBox.Load( THEME->GetPathTo(p==PLAYER_1 ? GRAPHIC_EVALUATION_STAGE_FRAME_P1 : GRAPHIC_EVALUATION_STAGE_FRAME_P2) );
m_sprBox.StopAnimating();
m_textNumber.SetText( ssprintf("%2d", iNumStagesCompleted) );
m_textST.SetText( "ST." );
}
+33
View File
@@ -0,0 +1,33 @@
#pragma once
/*
-----------------------------------------------------------------------------
Class: StageBox
Desc: bonus meters and max combo number.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "ActorFrame.h"
#include "Sprite.h"
#include "BitmapText.h"
#include "Quad.h"
#include "GameConstantsAndTypes.h"
class StageBox : public ActorFrame
{
public:
StageBox();
void SetStageInfo( PlayerNumber p, int iNumStagesCompleted );
protected:
Sprite m_sprBox;
BitmapText m_textTime;
BitmapText m_textNumber;
BitmapText m_textST;
};
+8 -8
View File
@@ -248,14 +248,6 @@ SOURCE=.\GameInput.h
# End Source File
# Begin Source File
SOURCE=.\GameplayStatistics.cpp
# End Source File
# Begin Source File
SOURCE=.\GameplayStatistics.h
# End Source File
# Begin Source File
SOURCE=.\GameTypes.h
# End Source File
# Begin Source File
@@ -688,6 +680,14 @@ SOURCE=.\SongInfoFrame.h
# End Source File
# Begin Source File
SOURCE=.\StageBox.cpp
# End Source File
# Begin Source File
SOURCE=.\StageBox.h
# End Source File
# Begin Source File
SOURCE=.\TextBanner.cpp
# End Source File
# Begin Source File
+6 -6
View File
@@ -357,12 +357,6 @@
<File
RelativePath=".\GameTypes.h">
</File>
<File
RelativePath="GameplayStatistics.cpp">
</File>
<File
RelativePath="GameplayStatistics.h">
</File>
<File
RelativePath=".\Grade.cpp">
</File>
@@ -658,6 +652,12 @@
<File
RelativePath="SongInfoFrame.h">
</File>
<File
RelativePath="StageBox.cpp">
</File>
<File
RelativePath="StageBox.h">
</File>
<File
RelativePath=".\TextBanner.cpp">
</File>
+2
View File
@@ -144,6 +144,8 @@ CString ThemeManager::GetPathTo( ThemeElement te, CString sThemeName )
case GRAPHIC_EVALUATION_BANNER_FRAME: sAssetPrefix = "Graphics\\evaluation banner frame"; break;
case GRAPHIC_EVALUATION_BONUS_FRAME_P1: sAssetPrefix = "Graphics\\evaluation bonus frame p1"; break;
case GRAPHIC_EVALUATION_BONUS_FRAME_P2: sAssetPrefix = "Graphics\\evaluation bonus frame p2"; break;
case GRAPHIC_EVALUATION_STAGE_FRAME_P1: sAssetPrefix = "Graphics\\evaluation stage frame p1"; break;
case GRAPHIC_EVALUATION_STAGE_FRAME_P2: sAssetPrefix = "Graphics\\evaluation stage frame p2"; break;
case GRAPHIC_EVALUATION_GRADE_FRAME: sAssetPrefix = "Graphics\\evaluation grade frame 1x2"; break;
case GRAPHIC_EVALUATION_GRADES: sAssetPrefix = "Graphics\\evaluation grades 1x7"; break;
case GRAPHIC_EVALUATION_JUDGE_LABELS: sAssetPrefix = "Graphics\\evaluation judge labels 1x6"; break;
+2
View File
@@ -68,6 +68,8 @@ enum ThemeElement {
GRAPHIC_EVALUATION_BANNER_FRAME,
GRAPHIC_EVALUATION_BONUS_FRAME_P1,
GRAPHIC_EVALUATION_BONUS_FRAME_P2,
GRAPHIC_EVALUATION_STAGE_FRAME_P1,
GRAPHIC_EVALUATION_STAGE_FRAME_P2,
GRAPHIC_EVALUATION_GRADE_FRAME,
GRAPHIC_EVALUATION_GRADES,
GRAPHIC_EVALUATION_JUDGE_LABELS,