Files
itgmania212121/stepmania/src/GameState.h
T
Glenn Maynard 9c867fdd70 We have two "gamestate Lua environments": mapEnv and m_Environment. The
former is a map<CString,CString>; the latter is a Lua table.  The former
is reset on gamestate reset, the latter is not.

Merge the map into the table, and eliminate it.  We only need one, and
it makes sense for a Lua environment to be a Lua table.

Do reset the table on Reset.  Otherwise, there's little point; if you want
to store data inside Lua, you don't need GameState to help.
2006-01-13 21:49:35 +00:00

337 lines
11 KiB
C++

/* GameState - Holds game data that is not saved between sessions. */
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include "GameConstantsAndTypes.h"
#include "SongOptions.h"
#include "Grade.h"
#include "Attack.h"
#include "RageTimer.h"
#include "Difficulty.h"
#include "MessageManager.h"
#include "SongOptions.h"
#include <map>
#include <deque>
#include <set>
class Song;
class Steps;
class Course;
class Trail;
class Game;
class Style;
class Character;
class TimingData;
class StageStats;
class PlayerState;
struct lua_State;
class LuaTable;
class Profile;
class PlayerOptions;
class GameState
{
public:
GameState();
~GameState();
void Reset();
void ApplyCmdline(); // called by Reset
void ApplyGameCommand( const CString &sCommand, PlayerNumber pn=PLAYER_INVALID );
void BeginGame(); // called when first player joins
void JoinPlayer( PlayerNumber pn );
void PlayersFinalized(); // called after a style is chosen, which means the number of players is finalized
void EndGame(); // called on ScreenGameOver, ScreenMusicScroll, ScreenCredits
void SaveCurrentSettingsToProfile( PlayerNumber pn ); // called at the beginning of each stage
Song* GetDefaultSong() const;
void Update( float fDelta );
//
// Main state info
//
void SetCurGame( const Game *pGame ); // Call this instead of m_pCurGame.Set to make sure PREFSMAN->m_sCurrentGame stays in sync
BroadcastOnChangePtr<const Game> m_pCurGame;
BroadcastOnChangePtr<const Style> m_pCurStyle;
bool m_bSideIsJoined[NUM_PLAYERS]; // left side, right side
bool m_bIsMultiPlayerJoined[NUM_MultiPlayer];
BroadcastOnChange<PlayMode> m_PlayMode; // many screens display different info depending on this value
int m_iCoins; // not "credits"
PlayerNumber m_MasterPlayerNumber; // used in Styles where one player controls both sides
bool m_bMultiplayer;
bool DifficultiesLocked();
bool ChangePreferredDifficulty( PlayerNumber pn, Difficulty dc );
bool ChangePreferredDifficulty( PlayerNumber pn, int dir );
bool ChangePreferredCourseDifficulty( PlayerNumber pn, CourseDifficulty cd );
bool ChangePreferredCourseDifficulty( PlayerNumber pn, int dir );
bool IsCourseDifficultyShown( CourseDifficulty cd );
Difficulty GetEasiestStepsDifficulty() const;
RageTimer m_timeGameStarted; // from the moment the first player pressed Start
LuaTable *m_Environment;
/* This is set to a random number per-game/round; it can be used for a random seed. */
int m_iGameSeed, m_iStageSeed;
bool PlayersCanJoin() const; // true if it's not too late for a player to join
int GetCoinsNeededToJoin() const;
bool EnoughCreditsToJoin() const { return GetCoinsNeededToJoin() <= 0; }
int GetNumSidesJoined() const;
const Game* GetCurrentGame();
const Style* GetCurrentStyle() const;
void GetPlayerInfo( PlayerNumber pn, bool& bIsEnabledOut, bool& bIsHumanOut );
bool IsPlayerEnabled( PlayerNumber pn ) const;
bool IsMultiPlayerEnabled( MultiPlayer mp ) const;
bool IsPlayerEnabled( const PlayerState* pPlayerState ) const;
int GetNumPlayersEnabled() const;
bool PlayerUsingBothSides() const;
bool IsHumanPlayer( PlayerNumber pn ) const;
int GetNumHumanPlayers() const;
PlayerNumber GetFirstHumanPlayer() const;
PlayerNumber GetFirstDisabledPlayer() const;
bool IsCpuPlayer( PlayerNumber pn ) const;
bool AnyPlayersAreCpu() const;
bool IsCourseMode() const;
bool IsBattleMode() const; /* not Rave */
bool ShowW1() const;
CString m_sLoadingMessage; // used in loading screen
BroadcastOnChange<CString> m_sPreferredSongGroup; // GROUP_ALL denotes no preferred group
BroadcastOnChange<CString> m_sPreferredCourseGroup; // GROUP_ALL denotes no preferred group
bool m_bChangedFailTypeOnScreenSongOptions; // true if FailType was changed in the song options screen
BroadcastOnChange1D<Difficulty,NUM_PLAYERS> m_PreferredDifficulty;
BroadcastOnChange1D<CourseDifficulty,NUM_PLAYERS> m_PreferredCourseDifficulty;// used in nonstop
BroadcastOnChange<SortOrder> m_SortOrder; // set by MusicWheel
SortOrder m_PreferredSortOrder; // used by MusicWheel
EditMode m_EditMode;
bool IsEditing() const { return m_EditMode != EditMode_INVALID; }
bool m_bDemonstrationOrJukebox; // ScreenGameplay does special stuff when this is true
bool m_bJukeboxUsesModifiers;
int m_iNumStagesOfThisSong;
int m_iCurrentStageIndex;
int GetStageIndex() const;
void BeginStage();
void CancelStage();
void CommitStageStats();
void FinishStage();
int GetNumStagesLeft() const;
bool IsFinalStage() const;
bool IsExtraStage() const;
bool IsExtraStage2() const;
Stage GetCurrentStage() const;
bool IsStagePossible( Stage s ) const;
int GetCourseSongIndex() const;
CString GetPlayerDisplayName( PlayerNumber pn ) const;
//
// State Info used during gameplay
//
// NULL on ScreenSelectMusic if the currently selected wheel item isn't a Song.
BroadcastOnChangePtr<Song> m_pCurSong;
// The last Song that the user manually changed to.
Song* m_pPreferredSong;
BroadcastOnChangePtr1D<Steps,NUM_PLAYERS> m_pCurSteps;
// NULL on ScreenSelectMusic if the currently selected wheel item isn't a Course.
BroadcastOnChangePtr<Course> m_pCurCourse;
// The last Course that the user manually changed to.
Course* m_pPreferredCourse;
BroadcastOnChangePtr1D<Trail,NUM_PLAYERS> m_pCurTrail;
bool m_bBackedOutOfFinalStage;
//
// Music statistics: Arcade: the current stage (one song). Oni/Endles: a single song in a course
//
// 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;
float m_fLightSongBeat; // g_fLightsFalloffSeconds ahead
bool m_bFreeze; // in the middle of a freeze
RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update
BroadcastOnChange<bool> m_bGameplayLeadIn;
void GetAllUsedNoteSkins( vector<CString> &out ) const;
static const float MUSIC_SECONDS_INVALID;
void ResetMusicStatistics(); // Call this when it's time to play a new song. Clears the values above.
void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer &timestamp = RageZeroTimer );
float GetSongPercent( float beat ) const;
bool IsPlayerInDanger( const PlayerState *pPlayerState ) const;
bool IsPlayerDead( const PlayerState *pPlayerState ) const;
bool AllAreInDangerOrWorse() const;
bool AllAreDead() const;
bool AllHumanHaveComboOf30OrMoreMisses() const;
bool OneIsHot() const;
// used in PLAY_MODE_BATTLE
float m_fOpponentHealthPercent;
// used in PLAY_MODE_RAVE
float m_fTugLifePercentP1;
// used in workout
bool m_bGoalComplete[NUM_PLAYERS];
void GetUndisplayedBeats( const PlayerState* pPlayerState, float TotalSeconds, float &StartBeat, float &EndBeat ) const; // only meaningful when a NoteField is in use
void RemoveAllActiveAttacks(); // called on end of song
PlayerNumber GetBestPlayer() const;
StageResult GetStageResult( PlayerNumber pn ) const;
void ResetStageStatistics(); // Call this when it's time to play a new stage.
// True if CommitStageStats() has been called and FinishStage() hasn't.
bool m_bStatsCommitted;
//
// Options stuff
//
SongOptions m_SongOptions;
SongOptions m_StoredSongOptions;
void GetDefaultPlayerOptions( PlayerOptions &po );
void GetDefaultSongOptions( SongOptions &so );
void ApplyModifiers( PlayerNumber pn, CString sModifiers );
void StoreSelectedOptions();
void RestoreSelectedOptions();
void RestoreStageOptions();
void ResetCurrentOptions();
bool IsDisqualified( PlayerNumber pn );
bool PlayerIsUsingModifier( PlayerNumber pn, const CString &sModifier );
SongOptions::FailType GetPlayerFailType( const PlayerState *pPlayerState ) const;
// character stuff
Character* m_pCurCharacters[NUM_PLAYERS];
bool HasEarnedExtraStage() const;
//
// Ranking Stuff
//
struct RankingFeat
{
enum { SONG, COURSE, CATEGORY } Type;
Song* pSong; // valid if Type == SONG
Steps* pSteps; // valid if Type == SONG
Course* pCourse; // valid if Type == COURSE
Grade grade;
int iScore;
float fPercentDP;
CString Banner;
CString Feat;
CString *pStringToFill;
};
void GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &vFeatsOut ) const;
bool AnyPlayerHasRankingFeats() const;
void StoreRankingName( PlayerNumber pn, CString name ); // Called by name entry screens
vector<CString*> m_vpsNamesThatWereFilled; // filled on StoreRankingName,
//
// Award stuff
//
// lowest priority in front, highest priority at the back.
deque<PerDifficultyAward> m_vLastPerDifficultyAwards[NUM_PLAYERS];
deque<PeakComboAward> m_vLastPeakComboAwards[NUM_PLAYERS];
//
// Attract stuff
//
int m_iNumTimesThroughAttract; // negative means play regardless of m_iAttractSoundFrequency setting
bool IsTimeToPlayAttractSounds() const;
void VisitAttractScreen( const CString sScreenName );
//
// PlayerState
//
PlayerState* m_pPlayerState[NUM_PLAYERS];
PlayerState* m_pMultiPlayerState[NUM_MultiPlayer];
//
// Preference wrappers
//
// These options have weird interactions depending on m_bEventMode,
// so wrap them
bool m_bTemporaryEventMode;
bool IsEventMode() const;
CoinMode GetCoinMode();
Premium GetPremium();
//
// Edit stuff
//
BroadcastOnChange<StepsType> m_stEdit;
BroadcastOnChangePtr<Steps> m_pEditSourceSteps;
BroadcastOnChange<StepsType> m_stEditSource;
BroadcastOnChange<int> m_iEditCourseEntryIndex;
BroadcastOnChange<CString> m_sEditLocalProfileID;
Profile* GetEditLocalProfile();
// Workout stuff
float GetGoalPercentComplete( PlayerNumber pn );
bool IsGoalComplete( PlayerNumber pn ) { return GetGoalPercentComplete( pn ) >= 1; }
// Sync changes stuff
TimingData *m_pTimingDataOriginal;
float m_fGlobalOffsetSecondsOriginal;
void ResetOriginalSyncData();
bool IsSyncDataChanged();
void SaveSyncChanges();
void RevertSyncChanges();
// Lua
void PushSelf( lua_State *L );
};
extern GameState* GAMESTATE; // global and accessable from anywhere in our program
#endif
/*
* (c) 2001-2004 Chris Danford, Glenn Maynard, Chris Gomez
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/