support noteskin-changing attacks

cache trick icons
change AI probability format
This commit is contained in:
Chris Danford
2003-04-22 04:54:04 +00:00
parent 0e11d79ec8
commit 4b7d640324
22 changed files with 267 additions and 219 deletions
+66 -66
View File
@@ -1,87 +1,87 @@
[Skill0] [Skill0]
MissCum=0.2 MissWeight=4
BooCum=0.4 BooWeight=4
GoodCum=0.6 GoodWeight=4
GreatCum=0.8 GreatWeight=40
PerfectCum=0.9 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=30
[Skill1] [Skill1]
MissCum=0.1 MissWeight=3
BooCum=0.3 BooWeight=3
GoodCum=0.5 GoodWeight=3
GreatCum=0.7 GreatWeight=38
PerfectCum=0.8 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=30
[Skill2] [Skill2]
MissCum=0.05 MissWeight=2
BooCum=0.2 BooWeight=2
GoodCum=0.4 GoodWeight=2
GreatCum=0.6 GreatWeight=36
PerfectCum=0.8 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=30
[Skill3] [Skill3]
MissCum=0.05 MissWeight=2
BooCum=0.1 BooWeight=1
GoodCum=0.3 GoodWeight=2
GreatCum=0.5 GreatWeight=34
PerfectCum=0.75 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=30
[Skill4] [Skill4]
MissCum=0.03 MissWeight=1
BooCum=0.05 BooWeight=1
GoodCum=0.25 GoodWeight=2
GreatCum=0.45 GreatWeight=32
PerfectCum=0.8 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=30
[Skill5] [Skill5]
MissCum=0.02 MissWeight=1
BooCum=0.04 BooWeight=1
GoodCum=0.20 GoodWeight=1
GreatCum=0.4 GreatWeight=30
PerfectCum=0.75 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=30
[Skill6] [Skill6]
MissCum=0.02 MissWeight=1
BooCum=0.03 BooWeight=
GoodCum=0.15 GoodWeight=1
GreatCum=0.35 GreatWeight=28
PerfectCum=0.7 PerfectWeight=36
MarvelousCum=1 MarvelousWeight=30
[Skill7] [Skill7]
MissCum=0.01 MissWeight=
BooCum=0.02 BooWeight=
GoodCum=0.10 GoodWeight=1
GreatCum=0.3 GreatWeight=26
PerfectCum=0.6 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=40
[Skill8] [Skill8]
MissCum=0.01 MissWeight=
BooCum=0.01 BooWeight=
GoodCum=0.05 GoodWeight=2
GreatCum=0.25 GreatWeight=18
PerfectCum=0.5 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=50
[Skill9] [Skill9]
MissCum=0 MissWeight=
BooCum=0 BooWeight=
GoodCum=0 GoodWeight=
GreatCum=0.2 GreatWeight=10
PerfectCum=0.5 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=60
[Skill10] [Skill10]
MissCum=0 MissWeight=
BooCum=0 BooWeight=
GoodCum=0 GoodWeight=
GreatCum=0 GreatWeight=
PerfectCum=0.3 PerfectWeight=30
MarvelousCum=1 MarvelousWeight=70
+6 -43
View File
@@ -85,13 +85,11 @@ void GameState::Reset()
m_StoredPlayerOptions[p].Init(); m_StoredPlayerOptions[p].Init();
} }
m_SongOptions.Init(); m_SongOptions.Init();
for( p=0; p<NUM_PLAYERS; p++ )
m_sPositioning[p] = "";
SAFE_DELETE( m_pPosition ); SAFE_DELETE( m_pPosition );
m_pPosition = new NoteFieldPositioning("Positioning.ini"); m_pPosition = new NoteFieldPositioning("Positioning.ini");
// apply defaults for( p=0; p<NUM_PLAYERS; p++ )
this->ApplyModifiers( PREFSMAN->m_sDefaultModifiers ); ApplyModifiers( (PlayerNumber)p, PREFSMAN->m_sDefaultModifiers );
for( p=0; p<NUM_PLAYERS; p++ ) for( p=0; p<NUM_PLAYERS; p++ )
{ {
@@ -416,43 +414,10 @@ void GameState::GetFinalEvalStatsAndSongs( StageStats& statsOut, vector<Song*>&
} }
void GameState::ApplyModifiers( CString sModifiers ) void GameState::ApplyModifiers( PlayerNumber pn, CString sModifiers )
{ {
for( int p=0; p<NUM_PLAYERS; p++ ) m_PlayerOptions[pn].FromString( sModifiers );
m_PlayerOptions[p].FromString( sModifiers );
m_SongOptions.FromString( sModifiers ); m_SongOptions.FromString( sModifiers );
sModifiers.MakeLower();
CStringArray asBits;
split( sModifiers, ",", asBits, true );
for( unsigned i=0; i<asBits.size(); i++ )
{
CString& sBit = asBits[i];
TrimLeft(sBit);
TrimRight(sBit);
// change NoteSkin
if( NOTESKIN->DoesNoteSkinExist(sBit) )
for( int p=0; p<NUM_PLAYERS; p++ )
NOTESKIN->SwitchNoteSkin( (PlayerNumber)p, sBit );
if( m_pPosition->IsValidModeForCurrentGame(sBit) )
for( int p=0; p<NUM_PLAYERS; p++ )
m_sPositioning[p] = sBit;
}
}
CString GameState::GetModifiers()
{
// This is really PLAYER_1's modifiers string!
CStringArray as;
#define PUSH_IF_NOT_EMPTY( s ) if( !s.empty() ) as.push_back( s );
PUSH_IF_NOT_EMPTY( m_PlayerOptions[PLAYER_1].GetString() );
PUSH_IF_NOT_EMPTY( m_SongOptions.GetString() );
PUSH_IF_NOT_EMPTY( m_sPositioning[PLAYER_1] );
return join( ",", as );
} }
/* Store the player's preferred options. This is called at the very beginning /* Store the player's preferred options. This is called at the very beginning
@@ -510,12 +475,10 @@ void GameState::RemoveAllInventory()
void GameState::RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn ) void GameState::RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn )
{ {
// rebuild player options // rebuild player options
PlayerOptions po = GAMESTATE->m_StoredPlayerOptions[pn]; PlayerOptions po = m_StoredPlayerOptions[pn];
for( int s=0; s<NUM_INVENTORY_SLOTS; s++ ) for( int s=0; s<NUM_INVENTORY_SLOTS; s++ )
{
po.FromString( m_ActiveAttacks[pn][s].sModifier ); po.FromString( m_ActiveAttacks[pn][s].sModifier );
} m_PlayerOptions[pn] = po;
GAMESTATE->m_PlayerOptions[pn] = po;
} }
int GameState::GetSumOfActiveAttackLevels( PlayerNumber pn ) int GameState::GetSumOfActiveAttackLevels( PlayerNumber pn )
+2 -4
View File
@@ -150,8 +150,7 @@ public:
SongOptions m_SongOptions; SongOptions m_SongOptions;
SongOptions m_StoredSongOptions; SongOptions m_StoredSongOptions;
void ApplyModifiers( CString sModifiers ); void ApplyModifiers( PlayerNumber pn, CString sModifiers );
CString GetModifiers();
void StoreSelectedOptions(); void StoreSelectedOptions();
void RestoreSelectedOptions(); void RestoreSelectedOptions();
@@ -175,7 +174,7 @@ public:
// used in PLAY_MODE_BATTLE // used in PLAY_MODE_BATTLE
Attack m_Inventory[NUM_PLAYERS][NUM_INVENTORY_SLOTS]; Attack m_Inventory[NUM_PLAYERS][NUM_INVENTORY_SLOTS];
bool m_bActiveAttackEndedThisUpdate[NUM_PLAYERS]; // flag so we can play sounds bool m_bActiveAttackEndedThisUpdate[NUM_PLAYERS]; // flag for other objects to watch (play sounds)
void LaunchAttack( PlayerNumber target, Attack aa ); void LaunchAttack( PlayerNumber target, Attack aa );
void RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn ); void RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn );
void RemoveAllActiveAttacks(); // called on end of song void RemoveAllActiveAttacks(); // called on end of song
@@ -202,7 +201,6 @@ public:
// //
// Arrow positioning // Arrow positioning
// //
CString m_sPositioning[NUM_PLAYERS]; /* The current positioning mode, or empty to use the normal positions. */
NoteFieldPositioning *m_pPosition; NoteFieldPositioning *m_pPosition;
}; };
+8 -8
View File
@@ -24,9 +24,11 @@
#define ITEM_COMBO( i ) THEME->GetMetricI("Inventory",ssprintf("Item%dCombo",i+1)) #define ITEM_COMBO( i ) THEME->GetMetricI("Inventory",ssprintf("Item%dCombo",i+1))
#define ITEM_EFFECT( i ) THEME->GetMetric ("Inventory",ssprintf("Item%dEffect",i+1)) #define ITEM_EFFECT( i ) THEME->GetMetric ("Inventory",ssprintf("Item%dEffect",i+1))
#define ITEM_LEVEL( i ) THEME->GetMetricI("Inventory",ssprintf("Item%dLevel",i+1)) #define ITEM_LEVEL( i ) THEME->GetMetricI("Inventory",ssprintf("Item%dLevel",i+1))
CachedThemeMetricF ITEM_USE_RATE_SECONDS("Inventory","ItemUseRateSeconds");
const PlayerNumber OPPOSITE_PLAYER[NUM_PLAYERS] = { PLAYER_2, PLAYER_1 }; const PlayerNumber OPPOSITE_PLAYER[NUM_PLAYERS] = { PLAYER_2, PLAYER_1 };
#define ITEM_USE_PROBABILITY (1.f/ITEM_USE_RATE_SECONDS)
struct Item struct Item
{ {
@@ -52,6 +54,7 @@ void ReloadItems()
Inventory::Inventory() Inventory::Inventory()
{ {
ITEM_USE_RATE_SECONDS.Refresh();
} }
void Inventory::Load( PlayerNumber pn ) void Inventory::Load( PlayerNumber pn )
@@ -114,18 +117,15 @@ void Inventory::Update( float fDelta )
if( GAMESTATE->m_PlayerController[m_PlayerNumber] != PC_HUMAN && if( GAMESTATE->m_PlayerController[m_PlayerNumber] != PC_HUMAN &&
GAMESTATE->m_fSongBeat < GAMESTATE->m_pCurSong->m_fLastBeat ) GAMESTATE->m_fSongBeat < GAMESTATE->m_pCurSong->m_fLastBeat )
{ {
// every one second, consider using an item // every 1 seconds, try to use an item
int iLastSecond = (int)(RageTimer::GetTimeSinceStart() - fDelta); int iLastSecond = (int)(RageTimer::GetTimeSinceStart() - fDelta);
int iThisSecond = (int)RageTimer::GetTimeSinceStart(); int iThisSecond = (int)RageTimer::GetTimeSinceStart();
if( iLastSecond != iThisSecond ) if( iLastSecond != iThisSecond )
{ {
int iSlotToConsider = rand()%NUM_INVENTORY_SLOTS; for( int s=0; s<NUM_INVENTORY_SLOTS; s++ )
bool bTimeToUse = (rand()%6)==0; if( !GAMESTATE->m_Inventory[m_PlayerNumber][s].IsBlank() )
if( !GAMESTATE->m_Inventory[m_PlayerNumber][iSlotToConsider].IsBlank() && if( randomf(0,1) < ITEM_USE_PROBABILITY )
bTimeToUse ) UseItem( s );
{
UseItem( iSlotToConsider );
}
} }
} }
} }
+7
View File
@@ -70,6 +70,13 @@ void NoteField::Load( NoteData* pNoteData, PlayerNumber pn, int iFirstPixelToDra
ASSERT( GetNumTracks() == GAMESTATE->GetCurrentStyleDef()->m_iColsPerPlayer ); ASSERT( GetNumTracks() == GAMESTATE->GetCurrentStyleDef()->m_iColsPerPlayer );
} }
void NoteField::ReloadNoteSkin()
{
// init note displays
for( int c=0; c<GetNumTracks(); c++ )
m_NoteDisplay[c].Load( c, m_PlayerNumber );
}
void NoteField::Update( float fDeltaTime ) void NoteField::Update( float fDeltaTime )
{ {
m_rectMarkerBar.Update( fDeltaTime ); m_rectMarkerBar.Update( fDeltaTime );
+1
View File
@@ -33,6 +33,7 @@ public:
virtual void DrawPrimitives(); virtual void DrawPrimitives();
void Load( NoteData* pNoteData, PlayerNumber pn, int iFirstPixelToDraw, int iLastPixelToDraw ); void Load( NoteData* pNoteData, PlayerNumber pn, int iFirstPixelToDraw, int iLastPixelToDraw );
void ReloadNoteSkin();
void RemoveTapNoteRow( int iIndex ); void RemoveTapNoteRow( int iIndex );
vector<bool> m_bIsHoldingHoldNote; // hack: Need this to know when to "light up" the center of hold notes vector<bool> m_bIsHoldingHoldNote; // hack: Need this to know when to "light up" the center of hold notes
+1 -1
View File
@@ -183,7 +183,7 @@ void NoteFieldPositioning::Load(PlayerNumber pn)
} }
/* Is there a custom mode with the current name that fits the current game? */ /* Is there a custom mode with the current name that fits the current game? */
const int ModeNum = GetID(GAMESTATE->m_sPositioning[pn]); const int ModeNum = GetID(GAMESTATE->m_PlayerOptions[pn].m_sPositioning);
if(ModeNum == -1) if(ModeNum == -1)
return; /* No, only use the style table settings. */ return; /* No, only use the style table settings. */
+61 -52
View File
@@ -15,7 +15,6 @@
#include "RageException.h" #include "RageException.h"
#include "GameState.h" #include "GameState.h"
#include "GameDef.h" #include "GameDef.h"
#include "IniFile.h"
#include "StyleInput.h" #include "StyleInput.h"
#include "StyleDef.h" #include "StyleDef.h"
#include "RageUtil.h" #include "RageUtil.h"
@@ -30,64 +29,41 @@ const CString NOTESKINS_DIR = "NoteSkins/";
NoteSkinManager::NoteSkinManager() NoteSkinManager::NoteSkinManager()
{ {
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_pIniMetrics[p] = new IniFile;
SwitchNoteSkin( (PlayerNumber)p, BASE_NOTESKIN_NAME );
}
} }
NoteSkinManager::~NoteSkinManager() NoteSkinManager::~NoteSkinManager()
{ {
for( int p=0; p<NUM_PLAYERS; p++ )
delete m_pIniMetrics[p];
} }
void NoteSkinManager::GetNoteSkinNames( Game game, CStringArray &AddTo ) const void NoteSkinManager::RefreshNoteSkinData( Game game )
{ {
GameDef* pGameDef = GAMEMAN->GetGameDefForGame( game ); GameDef* pGameDef = GAMEMAN->GetGameDefForGame( GAMESTATE->m_CurGame );
CString sBaseSkinFolder = NOTESKINS_DIR + pGameDef->m_szName + "/"; CString sBaseSkinFolder = NOTESKINS_DIR + pGameDef->m_szName + "/";
GetDirListing( sBaseSkinFolder + "*", AddTo, true ); CStringArray asNoteSkinNames;
GetDirListing( sBaseSkinFolder + "*", asNoteSkinNames, true );
int i;
// strip out "CVS" // strip out "CVS"
for( int i=AddTo.size()-1; i>=0; i-- ) for( i=asNoteSkinNames.size()-1; i>=0; i-- )
if( 0 == stricmp("cvs", AddTo[i]) ) if( 0 == stricmp("cvs", asNoteSkinNames[i]) )
AddTo.erase( AddTo.begin()+i, AddTo.begin()+i+1 ); asNoteSkinNames.erase( asNoteSkinNames.begin()+i, asNoteSkinNames.begin()+i+1 );
}
void NoteSkinManager::GetNoteSkinNames( CStringArray &AddTo ) const m_mapNameToData.clear();
{ for( i=0; i<asNoteSkinNames.size(); i++ )
GetNoteSkinNames( GAMESTATE->m_CurGame, AddTo );
}
bool NoteSkinManager::DoesNoteSkinExist( CString sSkinName ) const
{
CStringArray asSkinNames;
GetNoteSkinNames( asSkinNames );
for( unsigned i=0; i<asSkinNames.size(); i++ )
if( 0==stricmp(sSkinName, asSkinNames[i]) )
return true;
return false;
}
void NoteSkinManager::SwitchNoteSkin( PlayerNumber pn, CString sNewNoteSkin )
{
if( sNewNoteSkin == "" || !DoesNoteSkinExist(sNewNoteSkin) )
{ {
CStringArray as; CString sName = asNoteSkinNames[i];
GetNoteSkinNames( as ); sName.MakeLower();
ASSERT( !as.empty() ); m_mapNameToData[sName] = NoteSkinData();
LoadNoteSkinData( sName, m_mapNameToData[sName] );
/* Prefer "default" if it exists. */
sNewNoteSkin = as[0];
for(unsigned i = 0; i < as.size(); ++i)
if(!as[i].CompareNoCase("default")) sNewNoteSkin = "default";
} }
}
m_sCurNoteSkinName[pn] = sNewNoteSkin; void NoteSkinManager::LoadNoteSkinData( CString sNoteSkinName, NoteSkinData& data_out )
{
m_pIniMetrics[pn]->Reset(); data_out.sName = sNoteSkinName;
data_out.metrics.Reset();
/* Read only the default keys from the default noteskin. */ /* Read only the default keys from the default noteskin. */
IniFile defaults; IniFile defaults;
@@ -95,11 +71,40 @@ void NoteSkinManager::SwitchNoteSkin( PlayerNumber pn, CString sNewNoteSkin )
defaults.ReadFile(); defaults.ReadFile();
const IniFile::key *def = defaults.GetKey("NoteDisplay"); const IniFile::key *def = defaults.GetKey("NoteDisplay");
if(def) if(def)
m_pIniMetrics[pn]->SetValue("NoteDisplay", *def); data_out.metrics.SetValue("NoteDisplay", *def);
/* Read the active theme. */ /* Read the active theme. */
m_pIniMetrics[pn]->SetPath( GetNoteSkinDir(sNewNoteSkin)+"metrics.ini" ); data_out.metrics.SetPath( GetNoteSkinDir(sNoteSkinName)+"metrics.ini" );
m_pIniMetrics[pn]->ReadFile(); data_out.metrics.ReadFile();
}
void NoteSkinManager::GetNoteSkinNames( CStringArray &AddTo )
{
GetNoteSkinNames( GAMESTATE->m_CurGame, AddTo );
}
void NoteSkinManager::GetNoteSkinNames( Game game, CStringArray &AddTo )
{
RefreshNoteSkinData( game ); // now is a good time for this
for( map<CString,NoteSkinData>::const_iterator iter = m_mapNameToData.begin();
iter != m_mapNameToData.end();
++iter )
{
AddTo.push_back( iter->second.sName );
}
}
bool NoteSkinManager::DoesNoteSkinExist( CString sSkinName )
{
CStringArray asSkinNames;
GetNoteSkinNames( asSkinNames );
for( unsigned i=0; i<asSkinNames.size(); i++ )
if( 0==stricmp(sSkinName, asSkinNames[i]) )
return true;
return false;
} }
CString NoteSkinManager::GetNoteSkinDir( CString sSkinName ) CString NoteSkinManager::GetNoteSkinDir( CString sSkinName )
@@ -112,9 +117,12 @@ CString NoteSkinManager::GetNoteSkinDir( CString sSkinName )
CString NoteSkinManager::GetMetric( PlayerNumber pn, CString sButtonName, CString sValue ) // looks in GAMESTATE for the current Style CString NoteSkinManager::GetMetric( PlayerNumber pn, CString sButtonName, CString sValue ) // looks in GAMESTATE for the current Style
{ {
CString sReturn; CString sReturn;
if( m_pIniMetrics[pn]->GetValue( sButtonName, sValue, sReturn ) ) CString sNoteSkinName = GAMESTATE->m_PlayerOptions[pn].m_sNoteSkin;
sNoteSkinName.MakeLower();
NoteSkinData& data = m_mapNameToData[sNoteSkinName];
if( data.metrics.GetValue( sButtonName, sValue, sReturn ) )
return sReturn; return sReturn;
if( !m_pIniMetrics[pn]->GetValue( "NoteDisplay", sValue, sReturn ) ) if( !data.metrics.GetValue( "NoteDisplay", sValue, sReturn ) )
RageException::Throw( "Could not read metric '%s - %s' or 'NoteDisplay - %s'", RageException::Throw( "Could not read metric '%s - %s' or 'NoteDisplay - %s'",
sButtonName.GetString(), sValue.GetString(), sValue.GetString() ); sButtonName.GetString(), sValue.GetString(), sValue.GetString() );
return sReturn; return sReturn;
@@ -170,9 +178,10 @@ CString NoteSkinManager::GetPathTo( PlayerNumber pn, int col, CString sFileName
CString NoteSkinManager::GetPathTo( PlayerNumber pn, CString sButtonName, CString sFileName ) // looks in GAMESTATE for the current Style CString NoteSkinManager::GetPathTo( PlayerNumber pn, CString sButtonName, CString sFileName ) // looks in GAMESTATE for the current Style
{ {
CString sCurNoteSkinName = m_sCurNoteSkinName[pn]; CString sNoteSkinName = GAMESTATE->m_PlayerOptions[pn].m_sNoteSkin;
sNoteSkinName.MakeLower();
CString ret = GetPathTo( sCurNoteSkinName, sButtonName, sFileName ); CString ret = GetPathTo( sNoteSkinName, sButtonName, sFileName );
if( !ret.empty() ) // we found something if( !ret.empty() ) // we found something
return ret; return ret;
ret = GetPathTo( BASE_NOTESKIN_NAME, sButtonName, sFileName); ret = GetPathTo( BASE_NOTESKIN_NAME, sButtonName, sFileName);
@@ -180,7 +189,7 @@ CString NoteSkinManager::GetPathTo( PlayerNumber pn, CString sButtonName, CStrin
if( ret.empty() ) if( ret.empty() )
RageException::Throw( "The NoteSkin element '%s %s' could not be found in '%s' or '%s'.", RageException::Throw( "The NoteSkin element '%s %s' could not be found in '%s' or '%s'.",
sButtonName.GetString(), sFileName.GetString(), sButtonName.GetString(), sFileName.GetString(),
GetNoteSkinDir(sCurNoteSkinName).GetString(), GetNoteSkinDir(sNoteSkinName).GetString(),
GetNoteSkinDir(BASE_NOTESKIN_NAME).GetString() ); GetNoteSkinDir(BASE_NOTESKIN_NAME).GetString() );
return ret; return ret;
+15 -11
View File
@@ -15,8 +15,9 @@
#include "RageTypes.h" #include "RageTypes.h"
#include "Game.h" #include "Game.h"
#include "PlayerNumber.h" #include "PlayerNumber.h"
#include "IniFile.h"
#include <map>
class IniFile;
class NoteSkinManager class NoteSkinManager
{ {
@@ -24,11 +25,10 @@ public:
NoteSkinManager(); NoteSkinManager();
~NoteSkinManager(); ~NoteSkinManager();
void GetNoteSkinNames( Game game, CStringArray &AddTo ) const; void RefreshNoteSkinData( Game game );
void GetNoteSkinNames( CStringArray &AddTo ) const; // looks up current Game in GAMESTATE void GetNoteSkinNames( Game game, CStringArray &AddTo );
bool DoesNoteSkinExist( CString sSkinName ) const; // looks up current Game in GAMESTATE void GetNoteSkinNames( CStringArray &AddTo ); // looks up current Game in GAMESTATE
void SwitchNoteSkin( PlayerNumber pn, CString sNewNoteSkin ); // looks up current Game in GAMESTATE bool DoesNoteSkinExist( CString sSkinName ); // looks up current Game in GAMESTATE
CString GetCurNoteSkinName( PlayerNumber pn ) const { return m_sCurNoteSkinName[pn]; };
CString GetPathTo( PlayerNumber pn, int col, CString sFileName ); CString GetPathTo( PlayerNumber pn, int col, CString sFileName );
CString GetPathTo( PlayerNumber pn, CString sButtonName, CString sFileName ); CString GetPathTo( PlayerNumber pn, CString sButtonName, CString sFileName );
@@ -42,13 +42,17 @@ public:
static CString NoteSkinManager::ColToButtonName(int col); static CString NoteSkinManager::ColToButtonName(int col);
protected:
CString GetNoteSkinDir( CString sSkinName ); CString GetNoteSkinDir( CString sSkinName );
CString m_sCurNoteSkinName[NUM_PLAYERS]; protected:
IniFile* m_pIniMetrics[NUM_PLAYERS];
unsigned m_uHashForCurThemeMetrics[NUM_PLAYERS]; struct NoteSkinData
unsigned m_uHashForBaseThemeMetrics[NUM_PLAYERS]; {
CString sName;
IniFile metrics;
};
void LoadNoteSkinData( CString sNoteSkinName, NoteSkinData& data_out );
map<CString,NoteSkinData> m_mapNameToData;
}; };
+14 -5
View File
@@ -180,6 +180,8 @@ void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDi
m_GrayArrowRow.SetZoom( 0.5f ); m_GrayArrowRow.SetZoom( 0.5f );
m_GhostArrowRow.SetZoom( 0.5f ); m_GhostArrowRow.SetZoom( 0.5f );
} }
m_sLastSeenNoteSkin = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_sNoteSkin;
} }
void Player::Update( float fDeltaTime ) void Player::Update( float fDeltaTime )
@@ -276,6 +278,12 @@ void Player::Update( float fDeltaTime )
SetHoldNoteScore(i, hns); SetHoldNoteScore(i, hns);
} }
if( m_sLastSeenNoteSkin != GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_sNoteSkin )
{
m_NoteField.ReloadNoteSkin();
m_sLastSeenNoteSkin = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_sNoteSkin;
}
ActorFrame::Update( fDeltaTime ); ActorFrame::Update( fDeltaTime );
} }
@@ -416,7 +424,8 @@ void Player::Step( int col )
break; break;
default: default:
ASSERT(0); ASSERT(0);
score=TNS_NONE; score = TNS_NONE;
break;
} }
if( score==TNS_MARVELOUS && !PREFSMAN->m_bMarvelousTiming ) if( score==TNS_MARVELOUS && !PREFSMAN->m_bMarvelousTiming )
@@ -576,14 +585,14 @@ void Player::HandleTapRowScore( unsigned row )
ASSERT(iNumTapsInRow > 0); ASSERT(iNumTapsInRow > 0);
bool NoCheating = true; bool NoCheating = true;
/*#ifdef DEBUG #ifdef DEBUG
bool NoCheating = false; NoCheating = false;
#endif //DEBUG*/ #endif
if(GAMESTATE->m_bDemonstrationOrJukebox) if(GAMESTATE->m_bDemonstrationOrJukebox)
NoCheating = false; NoCheating = false;
// don't accumulate points if AutoPlay is on. // don't accumulate points if AutoPlay is on.
if( NoCheating && GAMESTATE->m_PlayerController[m_PlayerNumber] == PC_CPU ) if( NoCheating && GAMESTATE->m_PlayerController[m_PlayerNumber] == PC_AUTOPLAY )
return; return;
if(m_pScoreKeeper) if(m_pScoreKeeper)
+2
View File
@@ -85,6 +85,8 @@ protected:
ScoreDisplay* m_pScore; ScoreDisplay* m_pScore;
ScoreKeeper* m_pScoreKeeper; ScoreKeeper* m_pScoreKeeper;
Inventory* m_pInventory; Inventory* m_pInventory;
CString m_sLastSeenNoteSkin;
}; };
#endif #endif
+22 -11
View File
@@ -20,15 +20,19 @@
struct TapScoreDistribution struct TapScoreDistribution
{ {
float fCumulativeProbability[NUM_TAP_NOTE_SCORES]; float fPercent[NUM_TAP_NOTE_SCORES];
TapNoteScore GetTapNoteScore() TapNoteScore GetTapNoteScore()
{ {
float fRand = randomf(0,1); float fRand = randomf(0,1);
for( int i=TNS_MISS; i<=TNS_MARVELOUS; i++ ) float fCumulativePercent = 0;
if( fRand <= fCumulativeProbability[i] ) for( int i=0; i<=TNS_MARVELOUS; i++ )
{
fCumulativePercent += fPercent[i];
if( fRand <= fCumulativePercent )
return (TapNoteScore)i; return (TapNoteScore)i;
ASSERT(0); // the last probability must be 1.0, so we should never get here! }
ASSERT(0); // the fCumulativePercents must sum to 1.0, so we should never get here!
return TNS_MARVELOUS; return TNS_MARVELOUS;
} }
@@ -50,13 +54,20 @@ void PlayerAI::InitFromDisk()
RageException::Throw( "AI.ini: '%s' doesn't exist.", sKey.GetString() ); RageException::Throw( "AI.ini: '%s' doesn't exist.", sKey.GetString() );
TapScoreDistribution& dist = g_Distributions[i]; TapScoreDistribution& dist = g_Distributions[i];
dist.fCumulativeProbability[TNS_NONE] = 0; dist.fPercent[TNS_NONE] = 0;
ini.GetValueF( sKey, "MissCum", dist.fCumulativeProbability[TNS_MISS] ); ini.GetValueF( sKey, "MissWeight", dist.fPercent[TNS_MISS] );
ini.GetValueF( sKey, "BooCum", dist.fCumulativeProbability[TNS_BOO] ); ini.GetValueF( sKey, "BooWeight", dist.fPercent[TNS_BOO] );
ini.GetValueF( sKey, "GoodCum", dist.fCumulativeProbability[TNS_GOOD] ); ini.GetValueF( sKey, "GoodWeight", dist.fPercent[TNS_GOOD] );
ini.GetValueF( sKey, "GreatCum", dist.fCumulativeProbability[TNS_GREAT] ); ini.GetValueF( sKey, "GreatWeight", dist.fPercent[TNS_GREAT] );
ini.GetValueF( sKey, "PerfectCum", dist.fCumulativeProbability[TNS_PERFECT] ); ini.GetValueF( sKey, "PerfectWeight", dist.fPercent[TNS_PERFECT] );
dist.fCumulativeProbability[TNS_MARVELOUS] = 1; ini.GetValueF( sKey, "MarvelousWeight", dist.fPercent[TNS_MARVELOUS] );
float fSum = 0;
int j;
for( j=0; j<NUM_TAP_NOTE_SCORES; j++ )
fSum += dist.fPercent[j];
for( j=0; j<NUM_TAP_NOTE_SCORES; j++ )
dist.fPercent[j] /= fSum;
} }
} }
+13
View File
@@ -16,6 +16,7 @@
#include "GameState.h" #include "GameState.h"
#include "NoteFieldPositioning.h" #include "NoteFieldPositioning.h"
#include "NoteSkinManager.h"
void PlayerOptions::Init() void PlayerOptions::Init()
{ {
@@ -33,6 +34,9 @@ void PlayerOptions::Init()
m_bTimingAssist = false; m_bTimingAssist = false;
m_fPerspectiveTilt = 0; m_fPerspectiveTilt = 0;
m_bTimeSpacing = false; m_bTimeSpacing = false;
m_sPositioning = ""; // "null"
m_sNoteSkin = "default";
} }
void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds ) void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds )
@@ -132,6 +136,11 @@ CString PlayerOptions::GetString()
case +1: sReturn += "Space, "; break; case +1: sReturn += "Space, "; break;
} }
if( !m_sPositioning.empty() )
sReturn += m_sPositioning + ", ";
if( !m_sNoteSkin.empty() && m_sNoteSkin.CompareNoCase("default")!=0 )
sReturn += m_sNoteSkin + ", ";
if( sReturn.GetLength() > 2 ) if( sReturn.GetLength() > 2 )
sReturn.erase( sReturn.GetLength()-2 ); // delete the trailing ", " sReturn.erase( sReturn.GetLength()-2 ); // delete the trailing ", "
return sReturn; return sReturn;
@@ -196,6 +205,10 @@ void PlayerOptions::FromString( CString sOptions )
else if( sBit == "timingassist")m_bTimingAssist = true; else if( sBit == "timingassist")m_bTimingAssist = true;
else if( sBit == "incoming" ) m_fPerspectiveTilt = -1; else if( sBit == "incoming" ) m_fPerspectiveTilt = -1;
else if( sBit == "space" ) m_fPerspectiveTilt = +1; else if( sBit == "space" ) m_fPerspectiveTilt = +1;
else if( GAMESTATE->m_pPosition->IsValidModeForCurrentGame(sBit) )
m_sPositioning = sBit;
else if( NOTESKIN->DoesNoteSkinExist(sBit) )
m_sNoteSkin = sBit;
} }
} }
+2 -1
View File
@@ -77,7 +77,8 @@ struct PlayerOptions
bool m_bTimingAssist; bool m_bTimingAssist;
float m_fPerspectiveTilt; // -1 = near, 0 = overhead, +1 = space float m_fPerspectiveTilt; // -1 = near, 0 = overhead, +1 = space
bool m_bTimeSpacing; // instead of Beat spacing bool m_bTimeSpacing; // instead of Beat spacing
CString m_sPositioning; /* The current positioning mode, or empty to use the normal positions. */
CString m_sNoteSkin;
void NextAccel(); void NextAccel();
void NextEffect(); void NextEffect();
+2 -2
View File
@@ -351,8 +351,8 @@ retry:
PixFmtMasks[pixfmt].masks[0], PixFmtMasks[pixfmt].masks[1], PixFmtMasks[pixfmt].masks[0], PixFmtMasks[pixfmt].masks[1],
PixFmtMasks[pixfmt].masks[2], PixFmtMasks[pixfmt].masks[3]); PixFmtMasks[pixfmt].masks[2], PixFmtMasks[pixfmt].masks[3]);
//SM_SDL_OrderedDither(img, dst); SM_SDL_OrderedDither(img, dst);
SM_SDL_ErrorDiffusionDither(img, dst); //SM_SDL_ErrorDiffusionDither(img, dst);
SDL_FreeSurface(img); SDL_FreeSurface(img);
img = dst; img = dst;
} }
+6
View File
@@ -17,6 +17,7 @@
#include "RageLog.h" #include "RageLog.h"
#include "GameState.h" #include "GameState.h"
#include "ThemeManager.h" #include "ThemeManager.h"
#include "RageTextureManager.h"
ScoreDisplayBattle::ScoreDisplayBattle() ScoreDisplayBattle::ScoreDisplayBattle()
{ {
@@ -36,6 +37,11 @@ ScoreDisplayBattle::ScoreDisplayBattle()
m_ItemIcon[i].StopAnimating(); m_ItemIcon[i].StopAnimating();
this->AddChild( &m_ItemIcon[i] ); this->AddChild( &m_ItemIcon[i] );
} }
CStringArray asIconPaths;
GetDirListing( THEME->GetCurThemeDir()+"Graphic/ScoreDisplayBattle icon*.*", asIconPaths );
for( unsigned j=0; j<asIconPaths.size(); j++ )
TEXTUREMAN->CacheTexture( asIconPaths[j] );
} }
void ScoreDisplayBattle::Init( PlayerNumber pn ) void ScoreDisplayBattle::Init( PlayerNumber pn )
+2 -2
View File
@@ -241,7 +241,7 @@ ScreenEdit::ScreenEdit() : Screen("ScreenEdit")
GAMESTATE->m_PlayerOptions[PLAYER_1].m_fScrollSpeed = 1; GAMESTATE->m_PlayerOptions[PLAYER_1].m_fScrollSpeed = 1;
GAMESTATE->m_SongOptions.m_fMusicRate = 1; GAMESTATE->m_SongOptions.m_fMusicRate = 1;
NOTESKIN->SwitchNoteSkin( PLAYER_1, "note" ); // change noteskin before loading all of the edit Actors GAMESTATE->m_PlayerOptions[PLAYER_1].m_sNoteSkin = "note"; // change noteskin before loading all of the edit Actors
m_BGAnimation.LoadFromAniDir( THEME->GetPathToB("ScreenEdit background") ); m_BGAnimation.LoadFromAniDir( THEME->GetPathToB("ScreenEdit background") );
@@ -272,7 +272,7 @@ ScreenEdit::ScreenEdit() : Screen("ScreenEdit")
m_Clipboard.SetNumTracks( m_NoteFieldEdit.GetNumTracks() ); m_Clipboard.SetNumTracks( m_NoteFieldEdit.GetNumTracks() );
NOTESKIN->SwitchNoteSkin( PLAYER_1, "default" ); // change noteskin back to default before loading player GAMESTATE->m_PlayerOptions[PLAYER_1].m_sNoteSkin = "default"; // change noteskin back to default before loading player
m_Player.Load( PLAYER_1, &noteData, NULL, NULL, NULL, NULL ); m_Player.Load( PLAYER_1, &noteData, NULL, NULL, NULL, NULL );
GAMESTATE->m_PlayerController[PLAYER_1] = PC_HUMAN; GAMESTATE->m_PlayerController[PLAYER_1] = PC_HUMAN;
+27 -2
View File
@@ -35,6 +35,8 @@
#include "NoteFieldPositioning.h" #include "NoteFieldPositioning.h"
#include "LyricsLoader.h" #include "LyricsLoader.h"
#include "ActorUtil.h" #include "ActorUtil.h"
#include "NoteSkinManager.h"
#include "RageTextureManager.h"
// //
@@ -104,6 +106,30 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration ) : Screen("ScreenGameplay")
GAMESTATE->m_CurStageStats = StageStats(); // clear values GAMESTATE->m_CurStageStats = StageStats(); // clear values
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
{
// cache NoteSkin graphics
CStringArray asNames;
NOTESKIN->GetNoteSkinNames( asNames );
for( unsigned i=0; i<asNames.size(); i++ )
{
CString sDir = NOTESKIN->GetNoteSkinDir( asNames[i] );
CStringArray asGraphicPaths;
GetDirListing( sDir+"*.png", asGraphicPaths, false, true );
GetDirListing( sDir+"*.jpg", asGraphicPaths, false, true );
GetDirListing( sDir+"*.gif", asGraphicPaths, false, true );
GetDirListing( sDir+"*.bmp", asGraphicPaths, false, true );
for( unsigned j=0; j<asGraphicPaths.size(); j++ )
TEXTUREMAN->CacheTexture( asGraphicPaths[j] );
}
}
break;
}
// //
// fill in m_apSongsQueue, m_apNotesQueue, m_asModifiersQueue // fill in m_apSongsQueue, m_apNotesQueue, m_asModifiersQueue
@@ -563,8 +589,7 @@ void ScreenGameplay::LoadNextSong()
m_pScoreKeeper[p]->OnNextSong( GAMESTATE->GetCourseSongIndex(), GAMESTATE->m_pCurNotes[p] ); m_pScoreKeeper[p]->OnNextSong( GAMESTATE->GetCourseSongIndex(), GAMESTATE->m_pCurNotes[p] );
// Put courses options into effect. // Put courses options into effect.
GAMESTATE->m_PlayerOptions[p].FromString( m_asModifiersQueue[p][iPlaySongIndex] ); GAMESTATE->ApplyModifiers( (PlayerNumber)p, m_asModifiersQueue[p][iPlaySongIndex] );
GAMESTATE->m_SongOptions.FromString( m_asModifiersQueue[p][iPlaySongIndex] );
m_textPlayerOptions[p].SetText( GAMESTATE->m_PlayerOptions[p].GetString() ); m_textPlayerOptions[p].SetText( GAMESTATE->m_PlayerOptions[p].GetString() );
+4 -4
View File
@@ -148,7 +148,7 @@ void ScreenPlayerOptions::ImportOptions()
m_iSelectedOption[p][PO_NOTE_SKIN] = -1; m_iSelectedOption[p][PO_NOTE_SKIN] = -1;
for( unsigned j=0; j<m_OptionRow[PO_NOTE_SKIN].choices.size(); j++ ) for( unsigned j=0; j<m_OptionRow[PO_NOTE_SKIN].choices.size(); j++ )
{ {
if( 0==stricmp(m_OptionRow[PO_NOTE_SKIN].choices[j], NOTESKIN->GetCurNoteSkinName((PlayerNumber)p)) ) if( 0==stricmp(m_OptionRow[PO_NOTE_SKIN].choices[j], po.m_sNoteSkin) )
{ {
m_iSelectedOption[p][PO_NOTE_SKIN] = j; m_iSelectedOption[p][PO_NOTE_SKIN] = j;
break; break;
@@ -177,7 +177,7 @@ void ScreenPlayerOptions::ImportOptions()
{ {
vector<CString> &choices = m_OptionRow[PO_PERSPECTIVE].choices; vector<CString> &choices = m_OptionRow[PO_PERSPECTIVE].choices;
for(unsigned n = 3; n < choices.size(); ++n) for(unsigned n = 3; n < choices.size(); ++n)
if(!choices[n].CompareNoCase(GAMESTATE->m_sPositioning[p])) if(!choices[n].CompareNoCase(GAMESTATE->m_PlayerOptions[p].m_sPositioning))
m_iSelectedOption[p][PO_PERSPECTIVE] = n; m_iSelectedOption[p][PO_PERSPECTIVE] = n;
} }
@@ -225,7 +225,7 @@ void ScreenPlayerOptions::ExportOptions()
int iSelectedSkin = m_iSelectedOption[p][PO_NOTE_SKIN]; int iSelectedSkin = m_iSelectedOption[p][PO_NOTE_SKIN];
CString sNewSkin = m_OptionRow[PO_NOTE_SKIN].choices[iSelectedSkin]; CString sNewSkin = m_OptionRow[PO_NOTE_SKIN].choices[iSelectedSkin];
NOTESKIN->SwitchNoteSkin( (PlayerNumber)p, sNewSkin ); po.m_sNoteSkin = sNewSkin;
po.m_bHoldNotes = (m_iSelectedOption[p][PO_HOLD_NOTES] == 1); po.m_bHoldNotes = (m_iSelectedOption[p][PO_HOLD_NOTES] == 1);
@@ -241,7 +241,7 @@ void ScreenPlayerOptions::ExportOptions()
if(m_iSelectedOption[p][PO_PERSPECTIVE] > 2) if(m_iSelectedOption[p][PO_PERSPECTIVE] > 2)
{ {
const int choice = m_iSelectedOption[p][PO_PERSPECTIVE]; const int choice = m_iSelectedOption[p][PO_PERSPECTIVE];
GAMESTATE->m_sPositioning[p] = m_OptionRow[PO_PERSPECTIVE].choices[choice]; GAMESTATE->m_PlayerOptions[p].m_sPositioning = m_OptionRow[PO_PERSPECTIVE].choices[choice];
} }
} }
} }
-2
View File
@@ -53,8 +53,6 @@ ScreenRaveOptions::ScreenRaveOptions() :
g_RaveOptionsLines, g_RaveOptionsLines,
bComputerPlayersPresent ? 3 : 1, bComputerPlayersPresent ? 3 : 1,
false, false ); false, false );
SOUNDMAN->PlayMusic( THEME->GetPathToS("ScreenMachineOptions music") );
} }
void ScreenRaveOptions::ImportOptions() void ScreenRaveOptions::ImportOptions()
+3 -3
View File
@@ -73,7 +73,7 @@ ScreenSelectGroup::ScreenSelectGroup() : Screen("ScreenSelectGroup")
} }
// Add all group names to a map. // Add all group names to a map.
std::map<CString, CString> mapGroupNames; map<CString, CString> mapGroupNames;
for( i=0; i<aAllSongs.size(); i++ ) for( i=0; i<aAllSongs.size(); i++ )
{ {
const CString& sGroupName = aAllSongs[i]->m_sGroupName; const CString& sGroupName = aAllSongs[i]->m_sGroupName;
@@ -81,9 +81,9 @@ ScreenSelectGroup::ScreenSelectGroup() : Screen("ScreenSelectGroup")
} }
// copy group names into a vector // copy group names into a vector
std::vector<CString> asGroupNames; vector<CString> asGroupNames;
asGroupNames.push_back( "ALL MUSIC" ); // special group asGroupNames.push_back( "ALL MUSIC" ); // special group
for( std::map<CString, CString>::const_iterator iter = mapGroupNames.begin(); iter != mapGroupNames.end(); ++iter ) for( map<CString, CString>::const_iterator iter = mapGroupNames.begin(); iter != mapGroupNames.end(); ++iter )
asGroupNames.push_back( iter->first ); asGroupNames.push_back( iter->first );
// Add songs to the MusicList. // Add songs to the MusicList.
+1
View File
@@ -28,6 +28,7 @@ public:
bool DoesThemeExist( CString sThemeName ); bool DoesThemeExist( CString sThemeName );
void SwitchTheme( CString sThemeName ); void SwitchTheme( CString sThemeName );
CString GetCurThemeName() { return m_sCurThemeName; }; CString GetCurThemeName() { return m_sCurThemeName; };
CString GetCurThemeDir() { return GetThemeDirFromName(m_sCurThemeName); };
void NextTheme(); void NextTheme();
CString GetPathTo( ElementCategory category, CString sFileName, bool bOptional=false ); CString GetPathTo( ElementCategory category, CString sFileName, bool bOptional=false );