I still don't completely like this because after FinishStage(), if an extra stage has been earned, it is immediately in that stage which is sort of strange for SEval. Even worse, if an extra stage was earned in the past but not for the current stage, then the stage doesn't change. (E.g., earn extra stage but not second extra stage, or earn second extra stage.) So once an extra stage has been earned, SEval will be called twice for the same stage. A per-player m_iExtraStagesPlayed could be added to fix this, but it doesn't seem worth it.
- m_iPlayerCurrentStageIndexForCurrentCredit is changed to m_iPlayerStageTokens,
counting the number of stages left. This can be incremented and decremented
(as a bonus or penalty) with no weird side-effects; it is not used to determine
whether the player is on an extra stage. This is less brittle; it eliminates
special cases to avoid incrementing the counter and skipping into an extra stage.
- Stage tokens are subtracted for each song played, and a player is unjoined
when he runs out.
- Stage tokens are subtracted at the start of gameplay. If the player cancels,
they're "refunded". This differs from before, where the stage was incremented
at the end of gameplay. This makes the stage token counter meaningful during
gameplay; if this is done at the end, then it would be too high during gameplay.
- IsFinalStage is gone. If needed, use GetSmallestNumStagesLeftForAnyHumanPlayer.
- Extra stages are awarded by adding a stage token and incrementing
m_iAwardedExtraStages. If m_iAwardedExtraStages is 1, the player is
on his first extra stage; if 2, his second.
by lower level things (eg. InputMapper). However, concepts like
"joined players" and "human players" is a high-level, GAMESTATE
concept, and engine stuff shouldn't depend on that. Move the
GameState-depending stuff into GameState. Move
IsAnyPlayerUsingMemoryCard as well (and rename to HumanPlayer),
to fix MemoryCardManager dep.
(This should probably be used for more than this; this stuff needs a
cleanup ...)
(test case: pick a song with a stop near the beginning of the sample music,
eg. Fly With Me; no matter what the offset is set to, it should always show
the same pause on beat effects. This could do so while honoring the offset,
but getting that right in GameSoundManager is very tricky, and it's usually
not important for non-gameplay cosmetics.)
came up (like how to align beat effects correctly). Revert this and
fix assist tick differently.
Add GetBeatAndBPSFromElapsedTimeNoOffset, GetBeatFromElapsedTimeNoOffset,
GetElapsedTimeFromBeatNoOffset. Use them to ignore GlobalOffsetSeconds.
not TimingData. TimingData is a simple data structure, and shouldn't
be affected by hardware tweaks. This is also easier to bypass in cases
we don't want GlobalOffsetSeconds.
Don't adjust assist tick by GlobalOffsetSeconds.