add unlockable steps

This commit is contained in:
Chris Danford
2005-04-24 19:41:52 +00:00
parent 086ee3f376
commit ad5c70f7df
4 changed files with 123 additions and 92 deletions
+1 -1
View File
@@ -81,7 +81,7 @@ void ScreenReloadSongs::Update( float fDeltaTime )
ASSERT( !IsFirstUpdate() );
SONGMAN->Reload( m_LoadingWindow );
UNLOCKMAN->UpdateSongs();
UNLOCKMAN->UpdateCachedPointers();
SCREENMAN->SetNewScreen( NEXT_SCREEN );
}
+54 -58
View File
@@ -51,30 +51,25 @@ void ScreenUnlock::Init()
for( unsigned i=1; i <= NumUnlocks; i++ )
{
// get pertaining UnlockEntry
CString SongTitle = UNLOCKMAN->m_UnlockEntries[i-1].m_sName;
LOG->Trace("UnlockScreen: Searching for %s", SongTitle.c_str());
const UnlockEntry *pSong = UNLOCKMAN->FindLockEntry( SongTitle );
const UnlockEntry &entry = UNLOCKMAN->m_UnlockEntries[i-1];
const Song *pSong = entry.m_pSong;
if( pSong == NULL)
{
LOG->Trace("Can't find song %s", SongTitle.c_str());
continue;
}
Sprite* entry = new Sprite;
Sprite* pSpr = new Sprite;
// new unlock graphic
entry->Load( THEME->GetPathG("ScreenUnlock",ssprintf("%d icon", i)) );
pSpr->Load( THEME->GetPathG("ScreenUnlock",ssprintf("%d icon", i)) );
// set graphic location
entry->SetName( ssprintf("Unlock%d",i) );
SET_XY( *entry );
pSpr->SetName( ssprintf("Unlock%d",i) );
SET_XY( pSpr );
entry->RunCommands(IconCommand);
Unlocks.push_back(entry);
pSpr->RunCommands(IconCommand);
Unlocks.push_back(pSpr);
if ( !pSong->IsLocked() )
if ( !entry.IsLocked() )
this->AddChild(Unlocks[Unlocks.size() - 1]);
}
@@ -101,57 +96,61 @@ void ScreenUnlock::Init()
for(unsigned i = 1; i <= NumUnlocks; i++)
{
CString DisplayedSong = UNLOCKMAN->m_UnlockEntries[i-1].m_sName;
const UnlockEntry &entry = UNLOCKMAN->m_UnlockEntries[i-1];
DisplayedSong.MakeUpper();
const UnlockEntry *pSong = UNLOCKMAN->FindLockEntry(DisplayedSong);
if ( pSong == NULL ) // no such song
continue;
BitmapText* text = new BitmapText;
text->LoadFromFont( THEME->GetPathF("ScreenUnlock","text") );
text->SetHorizAlign( Actor::align_left );
text->SetZoom(ScrollingTextZoom);
if (pSong && pSong->m_pSong != NULL)
switch( entry.m_Type )
{
CString title = pSong->m_pSong->GetDisplayMainTitle();
CString subtitle = pSong->m_pSong->GetDisplaySubTitle();
if( subtitle != "" )
title = title + "\n" + subtitle;
text->SetMaxWidth( MaxWidth );
text->SetText( title );
}
else // song is missing, might be a course
{
Course *crs = SONGMAN->FindCourse( DisplayedSong );
if (crs != NULL)
case UnlockEntry::TYPE_SONG:
{
const Song *pSong = entry.m_pSong;
ASSERT( pSong );
CString title = pSong->GetDisplayMainTitle();
CString subtitle = pSong->GetDisplaySubTitle();
if( subtitle != "" )
title = title + "\n" + subtitle;
text->SetMaxWidth( MaxWidth );
text->SetText( crs->GetFullDisplayTitle() );
text->SetText( title );
}
break;
case UnlockEntry::TYPE_COURSE:
{
const Course *pCourse = entry.m_pCourse;
ASSERT( pCourse );
text->SetMaxWidth( MaxWidth );
text->SetText( pCourse->GetFullDisplayTitle() );
text->SetDiffuse( RageColor(0,1,0,1) );
}
else // entry isn't a song or course
{
text->SetText( "" );
text->SetDiffuse( RageColor(0.5,0,0,1) );
}
break;
default:
text->SetText( "" );
text->SetDiffuse( RageColor(0.5,0,0,1) );
break;
}
if (pSong != NULL && pSong->m_pSong != NULL)
if( entry.IsLocked() )
{
if( pSong->IsLocked() ) // song is locked
{
text->SetText("???");
text->SetZoomX(1);
} else { // song is unlocked, change color
RageColor color = SONGMAN->GetGroupColor(pSong->m_pSong->m_sGroupName);
text->SetGlobalDiffuseColor(color);
}
text->SetText("???");
text->SetZoomX(1);
}
else
{
// unlocked. change color
const Song *pSong = entry.m_pSong;
RageColor color = RageColor(1,1,1,1);
if( pSong )
color = SONGMAN->GetGroupColor(pSong->m_sGroupName);
text->SetGlobalDiffuseColor(color);
}
text->SetXY(ScrollingTextX, ScrollingTextStartY);
text->SetXY( ScrollingTextX, ScrollingTextStartY );
if (UNLOCK_TEXT_SCROLL == 3 && UNLOCK_TEXT_SCROLL_ROWS + i > NumUnlocks)
{ // special command for last unlocks when extreme-style scrolling is in effect
@@ -208,7 +207,7 @@ void ScreenUnlock::Init()
if (UNLOCK_TEXT_SCROLL == 3)
{
if ( !pSong->IsLocked() )
if ( !entry.IsLocked() )
LastUnlocks.push_back(i);
}
}
@@ -232,12 +231,9 @@ void ScreenUnlock::Init()
unsigned NextIcon = LastUnlocks[LastUnlocks.size() - i];
CString DisplayedSong = UNLOCKMAN->m_UnlockEntries[NextIcon-1].m_sName;
DisplayedSong.MakeUpper();
const UnlockEntry *pSong = UNLOCKMAN->FindLockEntry(DisplayedSong);
if (pSong->m_pSong == NULL)
const UnlockEntry &entry = UNLOCKMAN->m_UnlockEntries[NextIcon-1];
const Song *pSong = entry.m_pSong;
if( pSong == NULL )
continue;
BitmapText* NewText = new BitmapText;
@@ -245,8 +241,8 @@ void ScreenUnlock::Init()
NewText->LoadFromFont( THEME->GetPathF("ScreenUnlock","text") );
NewText->SetHorizAlign( Actor::align_left );
CString title = pSong->m_pSong->GetDisplayMainTitle();
CString subtitle = pSong->m_pSong->GetDisplaySubTitle();
CString title = pSong->GetDisplayMainTitle();
CString subtitle = pSong->GetDisplaySubTitle();
if( subtitle != "" )
title = title + "\n" + subtitle;
@@ -254,7 +250,7 @@ void ScreenUnlock::Init()
NewText->SetMaxWidth( MaxWidth );
NewText->SetText( title );
RageColor color = SONGMAN->GetGroupColor(pSong->m_pSong->m_sGroupName);
RageColor color = SONGMAN->GetGroupColor(pSong->m_sGroupName);
NewText->SetGlobalDiffuseColor(color);
NewText->SetXY(ScrollingTextX, ScrollingTextStartY);
+50 -27
View File
@@ -10,6 +10,7 @@
#include "ProfileManager.h"
#include "ThemeManager.h"
#include "Foreach.h"
#include "Steps.h"
#include <float.h>
UnlockManager* UNLOCKMAN = NULL; // global and accessable from anywhere in our program
@@ -103,7 +104,7 @@ bool UnlockManager::SongIsRouletteOnly( const Song *song ) const
return false;
const UnlockEntry *p = FindSong( song );
if( !p )
if( p == NULL )
return false;
/* If the song is locked by a code, and it's a roulette code, honor IsLocked. */
@@ -113,6 +114,18 @@ bool UnlockManager::SongIsRouletteOnly( const Song *song ) const
return p->IsLocked();
}
bool UnlockManager::StepsIsLocked( const Song *pSong, const Steps *pSteps ) const
{
if( !PREFSMAN->m_bUseUnlockSystem )
return false;
const UnlockEntry *p = FindSteps( pSong, pSteps );
if( p == NULL )
return false;
return p->IsLocked();
}
bool UnlockManager::ModifierIsLocked( const CString &sOneMod ) const
{
if( !PREFSMAN->m_bUseUnlockSystem )
@@ -125,19 +138,18 @@ bool UnlockManager::ModifierIsLocked( const CString &sOneMod ) const
return p->IsLocked();
}
const UnlockEntry *UnlockManager::FindLockEntry( CString songname ) const
const UnlockEntry *UnlockManager::FindSong( const Song *pSong ) const
{
FOREACH_CONST( UnlockEntry, m_UnlockEntries, e )
if( !songname.CompareNoCase(e->m_sName) )
if( e->m_pSong == pSong && e->m_dc == DIFFICULTY_INVALID )
return &(*e);
return NULL;
}
const UnlockEntry *UnlockManager::FindSong( const Song *pSong ) const
const UnlockEntry *UnlockManager::FindSteps( const Song *pSong, const Steps *pSteps ) const
{
FOREACH_CONST( UnlockEntry, m_UnlockEntries, e )
if( e->m_pSong == pSong )
if( e->m_pSong == pSong && e->m_dc == pSteps->GetDifficulty() )
return &(*e);
return NULL;
}
@@ -153,21 +165,11 @@ const UnlockEntry *UnlockManager::FindCourse( const Course *pCourse ) const
const UnlockEntry *UnlockManager::FindModifier( const CString &sOneMod ) const
{
FOREACH_CONST( UnlockEntry, m_UnlockEntries, e )
if( e->m_sName.CompareNoCase(sOneMod) == 0 )
if( e->m_cmd.GetArg(1).s.CompareNoCase(sOneMod) == 0 )
return &(*e);
return NULL;
}
UnlockEntry::UnlockEntry()
{
memset( m_fRequired, 0, sizeof(m_fRequired) );
m_iCode = -1;
m_pSong = NULL;
m_pCourse = NULL;
}
static float GetArcadePoints( const Profile *pProfile )
{
float fAP = 0;
@@ -292,17 +294,22 @@ void UnlockManager::Load()
if( sName == "song" )
{
current.m_Type = UnlockEntry::TYPE_SONG;
current.m_sName = (CString) cmd.GetArg(1);
current.m_cmd = cmd;
}
if( sName == "steps" )
{
current.m_Type = UnlockEntry::TYPE_STEPS;
current.m_cmd = cmd;
}
if( sName == "course" )
{
current.m_Type = UnlockEntry::TYPE_COURSE;
current.m_sName = (CString) cmd.GetArg(1);
current.m_cmd = cmd;
}
if( sName == "mod" )
{
current.m_Type = UnlockEntry::TYPE_MODIFIER;
current.m_sName = (CString) cmd.GetArg(1);
current.m_cmd = cmd;
}
else if( sName == "code" )
{
@@ -329,11 +336,11 @@ void UnlockManager::Load()
m_UnlockEntries.push_back( current );
}
UpdateSongs();
UpdateCachedPointers();
FOREACH_CONST( UnlockEntry, m_UnlockEntries, e )
{
CString str = ssprintf( "Unlock: %s; ", e->m_sName.c_str() );
CString str = ssprintf( "Unlock: %s; ", join("\n",e->m_cmd.m_vsArgs).c_str() );
FOREACH_UnlockType(j)
if( e->m_fRequired[j] )
str += ssprintf( "%s = %f; ", UnlockTypeToString(j).c_str(), e->m_fRequired[j] );
@@ -367,21 +374,37 @@ float UnlockManager::PointsUntilNextUnlock( UnlockType t ) const
/* Update the cached pointers. Only call this when it's likely to have changed,
* such as on load, or when a song title changes in the editor. */
void UnlockManager::UpdateSongs()
void UnlockManager::UpdateCachedPointers()
{
FOREACH( UnlockEntry, m_UnlockEntries, e )
{
switch( e->m_Type )
{
case UnlockEntry::TYPE_SONG:
e->m_pSong = SONGMAN->FindSong( e->m_sName );
e->m_pSong = SONGMAN->FindSong( e->m_cmd.GetArg(1) );
if( e->m_pSong == NULL )
LOG->Warn( "Unlock: Cannot find song matching \"%s\"", e->m_sName.c_str() );
LOG->Warn( "Unlock: Cannot find song matching \"%s\"", e->m_cmd.GetArg(1).s.c_str() );
break;
case UnlockEntry::TYPE_STEPS:
e->m_pSong = SONGMAN->FindSong( e->m_cmd.GetArg(1) );
if( e->m_pSong == NULL )
{
LOG->Warn( "Unlock: Cannot find song matching \"%s\"", e->m_cmd.GetArg(1).s.c_str() );
break;
}
e->m_dc = StringToDifficulty( e->m_cmd.GetArg(2) );
if( e->m_dc == DIFFICULTY_INVALID )
{
LOG->Warn( "Unlock: Invalid difficulty \"%s\"", e->m_cmd.GetArg(2).s.c_str() );
break;
}
break;
case UnlockEntry::TYPE_COURSE:
e->m_pCourse = SONGMAN->FindCourse( e->m_sName );
e->m_pCourse = SONGMAN->FindCourse( e->m_cmd.GetArg(1) );
if( e->m_pCourse == NULL )
LOG->Warn( "Unlock: Cannot find course matching \"%s\"", e->m_sName.c_str() );
LOG->Warn( "Unlock: Cannot find course matching \"%s\"", e->m_cmd.GetArg(1).s.c_str() );
break;
case UnlockEntry::TYPE_MODIFIER:
// nothing to cache
+18 -6
View File
@@ -4,6 +4,7 @@
#define UNLOCK_SYSTEM_H
#include "Grade.h"
#include "Command.h"
#include <set>
class Song;
@@ -26,15 +27,26 @@ enum UnlockType
struct UnlockEntry
{
UnlockEntry();
UnlockEntry()
{
m_Type = TYPE_INVALID;
enum Type { TYPE_SONG, TYPE_COURSE, TYPE_MODIFIER };
m_pSong = NULL;
m_dc = DIFFICULTY_INVALID;
m_pCourse = NULL;
ZERO( m_fRequired );
m_iCode = -1;
}
enum Type { TYPE_SONG, TYPE_STEPS, TYPE_COURSE, TYPE_MODIFIER, NUM_TYPES, TYPE_INVALID };
Type m_Type;
CString m_sName;
Command m_cmd;
/* A cached pointer to the song or course this entry refers to. Only one of
* these will be non-NULL. */
Song *m_pSong;
Difficulty m_dc;
Course *m_pCourse;
float m_fRequired[NUM_UNLOCK_TYPES];
@@ -59,14 +71,13 @@ public:
// Used on select screens:
bool SongIsLocked( const Song *song ) const;
bool SongIsRouletteOnly( const Song *song ) const;
bool StepsIsLocked( const Song *pSong, const Steps *pSteps ) const;
bool CourseIsLocked( const Course *course ) const;
bool ModifierIsLocked( const CString &sOneMod ) const;
// Gets number of unlocks for title screen
int GetNumUnlocks() const;
const UnlockEntry *FindLockEntry( CString lockname ) const;
void GetPoints( const Profile *pProfile, float fScores[NUM_UNLOCK_TYPES] ) const;
// Unlock an entry by code.
@@ -88,7 +99,7 @@ public:
vector<UnlockEntry> m_UnlockEntries;
// If global song or course points change, call to update
void UpdateSongs();
void UpdateCachedPointers();
// Lua
void PushSelf( lua_State *L );
@@ -98,6 +109,7 @@ private:
void Load();
const UnlockEntry *FindSong( const Song *pSong ) const;
const UnlockEntry *FindSteps( const Song *pSong, const Steps *pSteps ) const;
const UnlockEntry *FindCourse( const Course *pCourse ) const;
const UnlockEntry *FindModifier( const CString &sOneMod ) const;