From fcc6c4408a9577377cc2940266f2a897a2c3d4e6 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Thu, 7 Jul 2005 22:08:05 +0000 Subject: [PATCH] working on SSelectProfile --- stepmania/src/GameCommand.cpp | 36 ++++- stepmania/src/GameCommand.h | 5 + stepmania/src/GameState.cpp | 4 + stepmania/src/GameState.h | 3 + stepmania/src/ScreenSelectMaster.cpp | 9 +- stepmania/src/ScreenSelectProfile.cpp | 218 ++++++++++++++++++++++++++ stepmania/src/ScreenSelectProfile.h | 42 +++++ 7 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 stepmania/src/ScreenSelectProfile.cpp create mode 100644 stepmania/src/ScreenSelectProfile.h diff --git a/stepmania/src/GameCommand.cpp b/stepmania/src/GameCommand.cpp index 6bd25e4edb..53bbc5f27b 100644 --- a/stepmania/src/GameCommand.cpp +++ b/stepmania/src/GameCommand.cpp @@ -55,6 +55,7 @@ void GameCommand::Init() m_iWeightPounds = -1; m_iGoalCalories = -1; m_GoalType = GOAL_INVALID; + m_sProfileID = ""; m_bClearBookkeepingData = false; m_bClearMachineStats = false; @@ -137,6 +138,8 @@ bool GameCommand::DescribesCurrentMode( PlayerNumber pn ) const return false; if( m_GoalType != GOAL_INVALID && PROFILEMAN->GetProfile(pn)->m_GoalType != m_GoalType ) return false; + if( !m_sProfileID.empty() && PREFSMAN->GetDefaultLocalProfileID(pn).Get() != m_sProfileID ) + return false; return true; } @@ -334,6 +337,11 @@ void GameCommand::LoadOne( const Command& cmd ) m_GoalType = StringToGoalType( sValue ); } + else if( sName == "profileid" ) + { + m_sProfileID = sValue; + } + else if( sName == "unlock" ) { m_iUnlockIndex = atoi( sValue ); @@ -778,6 +786,9 @@ void GameCommand::ApplySelf( const vector &vpns ) const if( m_GoalType != GOAL_INVALID ) FOREACH_CONST( PlayerNumber, vpns, pn ) PROFILEMAN->GetProfile(*pn)->m_GoalType = m_GoalType; + if( !m_sProfileID.empty() ) + FOREACH_CONST( PlayerNumber, vpns, pn ) + PREFSMAN->GetDefaultLocalProfileID(*pn).Set( m_sProfileID ); /* If we're going to stop music, do so before preparing new screens, so we don't * stop music between preparing screens and loading screens. */ @@ -1076,13 +1087,36 @@ bool GameCommand::IsZero() const m_SortOrder != SORT_INVALID || m_iWeightPounds != -1 || m_iGoalCalories != -1 || - m_GoalType != GOAL_INVALID + m_GoalType != GOAL_INVALID || + !m_sProfileID.empty() ) return false; return true; } +// lua start +#include "LuaBinding.h" +#include "Game.h" + +class LunaGameCommand: public Luna +{ +public: + LunaGameCommand() { LUA->Register( Register ); } + + static int GetProfileID( T* p, lua_State *L ) { lua_pushstring(L, p->m_sProfileID ); return 1; } + + static void Register(lua_State *L) + { + ADD_METHOD( GetProfileID ) + + Luna::Register( L ); + } +}; + +LUA_REGISTER_CLASS( GameCommand ) +// lua end + /* * (c) 2001-2004 Chris Danford, Glenn Maynard * All rights reserved. diff --git a/stepmania/src/GameCommand.h b/stepmania/src/GameCommand.h index 41c2d3b82a..5d31f7350b 100644 --- a/stepmania/src/GameCommand.h +++ b/stepmania/src/GameCommand.h @@ -17,6 +17,7 @@ class Trail; class Character; class Style; class Game; +struct lua_State; struct GameCommand // used in SelectMode { @@ -71,6 +72,7 @@ public: int m_iWeightPounds; // -1 == none specified int m_iGoalCalories; // -1 == none specified GoalType m_GoalType; + CString m_sProfileID; bool m_bClearBookkeepingData; bool m_bClearMachineStats; @@ -84,6 +86,9 @@ public: bool m_bResetToFactoryDefaults; bool m_bStopMusic; bool m_bApplyDefaultOptions; + + // Lua + virtual void PushSelf( lua_State *L ); }; #endif diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index fed408b9ce..5122f90e35 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -260,6 +260,8 @@ void GameState::Reset() m_bBackedOutOfFinalStage = false; + m_sEditingProfileID = ""; + ApplyCmdline(); } @@ -2073,6 +2075,7 @@ public: lua_pushboolean(L, p->GetStageResult(pn)==RESULT_WIN); return 1; } static int GetCurrentGame( T* p, lua_State *L ) { const_cast(p->GetCurrentGame())->PushSelf( L ); return 1; } + static int GetEditingProfileID( T* p, lua_State *L ) { lua_pushstring(L, p->m_sEditingProfileID ); return 1; } static void Register(lua_State *L) { ADD_METHOD( IsPlayerEnabled ) @@ -2122,6 +2125,7 @@ public: ADD_METHOD( IsSyncDataChanged ) ADD_METHOD( IsWinner ) ADD_METHOD( GetCurrentGame ) + ADD_METHOD( GetEditingProfileID ) Luna::Register( L ); diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index 4747586a56..2fe406d00d 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -311,6 +311,9 @@ public: void SaveSyncChanges(); void RevertSyncChanges(); + // profile stuff + CString m_sEditingProfileID; + // Lua void PushSelf( lua_State *L ); }; diff --git a/stepmania/src/ScreenSelectMaster.cpp b/stepmania/src/ScreenSelectMaster.cpp index 6d6b323928..440c66d5f7 100644 --- a/stepmania/src/ScreenSelectMaster.cpp +++ b/stepmania/src/ScreenSelectMaster.cpp @@ -114,11 +114,18 @@ void ScreenSelectMaster::Init() for( unsigned c=0; cGet(); + mc.PushSelf( L ); + GAMESTATE->m_Environment->Set( L, "ThisGameCommand" ); m_sprScroll[c][*p].Load( THEME->GetPathG(m_sName,ssprintf("Scroll Choice%s",mc.m_sName.c_str())+APPEND_STRING_WITH_SPACE(*p)) ); m_sprScroll[c][*p]->SetName( "Scroll"+APPEND_STRING_NO_SPACE(*p) ); m_Scroller[*p].AddChild( m_sprScroll[c][*p] ); + + GAMESTATE->m_Environment->Unset( L, "ThisGameCommand" ); + LUA->Release( L ); } } } diff --git a/stepmania/src/ScreenSelectProfile.cpp b/stepmania/src/ScreenSelectProfile.cpp new file mode 100644 index 0000000000..eb9c993a27 --- /dev/null +++ b/stepmania/src/ScreenSelectProfile.cpp @@ -0,0 +1,218 @@ +#include "global.h" + +#include "ScreenSelectProfile.h" +#include "ScreenMiniMenu.h" +#include "ProfileManager.h" +#include "ScreenTextEntry.h" +#include "ScreenPrompt.h" +#include "RageUtil.h" +#include "GameState.h" + +AutoScreenMessage( SM_BackFromEnterName ) +AutoScreenMessage( SM_BackFromProfileContextMenu ) +AutoScreenMessage( SM_BackFromDelete ) + +const int PROFILE_MAX_NAME_LENGTH = 64; + +static bool ValidateProfileName( const CString &sAnswer, CString &sErrorOut ) +{ + CString sCurrentProfileOldName = PROFILEMAN->ProfileIDToName( GAMESTATE->m_sEditingProfileID ); + vector vsProfileNames; + PROFILEMAN->GetLocalProfileNames( vsProfileNames ); + bool bAlreadyAProfileWithThisName = find( vsProfileNames.begin(), vsProfileNames.end(), sAnswer ) != vsProfileNames.end(); + + if( sAnswer == "" ) + { + sErrorOut = "Profile name cannot be blank."; + return false; + } + else if( sAnswer == sCurrentProfileOldName ) + { + return true; + } + else if( bAlreadyAProfileWithThisName ) + { + sErrorOut = "There is already another profile with this name. Please choose a different name."; + return false; + } + + return true; +} + +enum ContextMenuAnswer +{ + A_EDIT, + A_RENAME, + A_DELETE, + A_CANCEL, +}; + +static MenuDef g_ProfileContextMenu( + "ScreenMiniMenuProfiles", + MenuRowDef( A_EDIT, "Edit", true, EDIT_MODE_PRACTICE, 0, "" ), + MenuRowDef( A_RENAME, "Rename", true, EDIT_MODE_PRACTICE, 0, "" ), + MenuRowDef( A_DELETE, "Delete", true, EDIT_MODE_PRACTICE, 0, "" ), + MenuRowDef( A_CANCEL, "Cancel", true, EDIT_MODE_PRACTICE, 0, "" ) +); + +REGISTER_SCREEN_CLASS( ScreenSelectProfile ); +ScreenSelectProfile::ScreenSelectProfile( CString sName ) : + ScreenSelectMaster( sName ) +{ + +} + +void ScreenSelectProfile::Init() +{ + // Fill m_aGameCommands overriding whatever is in metrics + GameCommand gc; + m_aGameCommands.clear(); + + gc.m_sName = "create"; + m_aGameCommands.push_back( gc ); + + vector vsProfileNames; + PROFILEMAN->GetLocalProfileNames( vsProfileNames ); + + FOREACH_CONST( CString, vsProfileNames, s ) + { + gc.m_sName = "profile"; + m_aGameCommands.push_back( gc ); + } + + gc.m_sName = "exit"; + m_aGameCommands.push_back( gc ); + + + ScreenSelectMaster::Init(); +} + +ScreenSelectProfile::~ScreenSelectProfile() +{ + +} + +void ScreenSelectProfile::HandleScreenMessage( const ScreenMessage SM ) +{ + if( SM == SM_BackFromEnterName ) + { + if( !ScreenTextEntry::s_bCancelledLast ) + { + ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this + + CString sNewName = ScreenTextEntry::s_sLastAnswer; + if( GAMESTATE->m_sEditingProfileID.empty() ) + { + // create + bool bResult = PROFILEMAN->CreateLocalProfile( sNewName ); + if( bResult ) + SCREENMAN->SetNewScreen( m_sName ); // reload + else + ScreenPrompt::Prompt( SM_None, ssprintf("Error creating profile '%s'.", sNewName.c_str()) ); + } + else + { + // rename + bool bResult = PROFILEMAN->RenameLocalProfile( GAMESTATE->m_sEditingProfileID, sNewName ); + if( bResult ) + SCREENMAN->SetNewScreen( m_sName ); // reload + else + ScreenPrompt::Prompt( SM_None, ssprintf("Error renaming profile '%s'.", sNewName.c_str()) ); + } + } + } + else if( SM == SM_BackFromProfileContextMenu ) + { + if( !ScreenMiniMenu::s_bCancelled ) + { + switch( ScreenMiniMenu::s_iLastRowCode ) + { + default: + ASSERT(0); + case A_EDIT: + SCREENMAN->SetNewScreen( "ScreenOptionsEditProfile" ); + break; + case A_RENAME: + { + CString sCurrentProfileName = PROFILEMAN->ProfileIDToName( GAMESTATE->m_sEditingProfileID ); + ScreenTextEntry::TextEntry( SM_BackFromEnterName, "Enter a name for a new profile.", sCurrentProfileName, PROFILE_MAX_NAME_LENGTH, ValidateProfileName ); + } + break; + case A_DELETE: + { + CString sCurrentProfileName = PROFILEMAN->ProfileIDToName( GAMESTATE->m_sEditingProfileID ); + CString sMessage = ssprintf( "Are you sure you want to delete the profile '%s'?", sCurrentProfileName.c_str() ); + ScreenPrompt::Prompt( SM_BackFromDelete, sMessage, PROMPT_YES_NO ); + } + break; + case A_CANCEL: + SCREENMAN->PlayInvalidSound(); + break; + } + } + } + else if( SM == SM_BackFromDelete ) + { + if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) + { + PROFILEMAN->DeleteLocalProfile( GAMESTATE->m_sEditingProfileID ); + SCREENMAN->SetNewScreen( m_sName ); // reload + } + } + + ScreenSelectMaster::HandleScreenMessage( SM ); +} + +/* +void ScreenSelectProfile::ProcessMenuStart( PlayerNumber pn, const InputEventType type ) +{ + int iRow = GetCurrentRow();; + OptionRow &row = *m_pRows[iRow]; + + if( iRow == 0 ) // "create new" + { + s_sLastSelectedProfileID = ""; + ScreenTextEntry::TextEntry( SM_BackFromEnterName, "Enter a name for a new profile.", PROFILEMAN->GetNewProfileDefaultName(), PROFILE_MAX_NAME_LENGTH, ValidateProfileName ); + } + else if( row.GetRowType() == OptionRow::ROW_EXIT ) + { + s_sLastSelectedProfileID = ""; + ScreenOptions::ProcessMenuStart( pn, type ); + } + else + { + int iProfileIndex = iRow - 1; + vector vsProfileIDs; + PROFILEMAN->GetLocalProfileIDs( vsProfileIDs ); + s_sLastSelectedProfileID = vsProfileIDs[ iProfileIndex ]; + int iThrowAway, iX, iY; + GetWidthXY( PLAYER_1, iRow, 0, iThrowAway, iX, iY ); + ScreenMiniMenu::MiniMenu( &g_ProfileContextMenu, SM_BackFromProfileContextMenu, SM_BackFromProfileContextMenu, (float)iX, (float)iY ); + } +} +*/ + +/* + * (c) 2003-2004 Chris Danford + * 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. + */ diff --git a/stepmania/src/ScreenSelectProfile.h b/stepmania/src/ScreenSelectProfile.h new file mode 100644 index 0000000000..29c1d9c2b7 --- /dev/null +++ b/stepmania/src/ScreenSelectProfile.h @@ -0,0 +1,42 @@ +#ifndef ScreenSelectProfile_H +#define ScreenSelectProfile_H + +#include "ScreenSelectMaster.h" + +class ScreenSelectProfile : public ScreenSelectMaster +{ +public: + ScreenSelectProfile( CString sName ); + virtual void Init(); + virtual ~ScreenSelectProfile(); + +protected: + virtual void HandleScreenMessage( const ScreenMessage SM ); +}; + +#endif + +/* + * (c) 2003-2004 Chris Danford + * 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. + */