support noteskin-changing attacks
cache trick icons change AI probability format
This commit is contained in:
+66
-66
@@ -1,87 +1,87 @@
|
||||
[Skill0]
|
||||
MissCum=0.2
|
||||
BooCum=0.4
|
||||
GoodCum=0.6
|
||||
GreatCum=0.8
|
||||
PerfectCum=0.9
|
||||
MarvelousCum=1
|
||||
MissWeight=4
|
||||
BooWeight=4
|
||||
GoodWeight=4
|
||||
GreatWeight=40
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=30
|
||||
|
||||
[Skill1]
|
||||
MissCum=0.1
|
||||
BooCum=0.3
|
||||
GoodCum=0.5
|
||||
GreatCum=0.7
|
||||
PerfectCum=0.8
|
||||
MarvelousCum=1
|
||||
MissWeight=3
|
||||
BooWeight=3
|
||||
GoodWeight=3
|
||||
GreatWeight=38
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=30
|
||||
|
||||
[Skill2]
|
||||
MissCum=0.05
|
||||
BooCum=0.2
|
||||
GoodCum=0.4
|
||||
GreatCum=0.6
|
||||
PerfectCum=0.8
|
||||
MarvelousCum=1
|
||||
MissWeight=2
|
||||
BooWeight=2
|
||||
GoodWeight=2
|
||||
GreatWeight=36
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=30
|
||||
|
||||
[Skill3]
|
||||
MissCum=0.05
|
||||
BooCum=0.1
|
||||
GoodCum=0.3
|
||||
GreatCum=0.5
|
||||
PerfectCum=0.75
|
||||
MarvelousCum=1
|
||||
MissWeight=2
|
||||
BooWeight=1
|
||||
GoodWeight=2
|
||||
GreatWeight=34
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=30
|
||||
|
||||
[Skill4]
|
||||
MissCum=0.03
|
||||
BooCum=0.05
|
||||
GoodCum=0.25
|
||||
GreatCum=0.45
|
||||
PerfectCum=0.8
|
||||
MarvelousCum=1
|
||||
MissWeight=1
|
||||
BooWeight=1
|
||||
GoodWeight=2
|
||||
GreatWeight=32
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=30
|
||||
|
||||
[Skill5]
|
||||
MissCum=0.02
|
||||
BooCum=0.04
|
||||
GoodCum=0.20
|
||||
GreatCum=0.4
|
||||
PerfectCum=0.75
|
||||
MarvelousCum=1
|
||||
MissWeight=1
|
||||
BooWeight=1
|
||||
GoodWeight=1
|
||||
GreatWeight=30
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=30
|
||||
|
||||
[Skill6]
|
||||
MissCum=0.02
|
||||
BooCum=0.03
|
||||
GoodCum=0.15
|
||||
GreatCum=0.35
|
||||
PerfectCum=0.7
|
||||
MarvelousCum=1
|
||||
MissWeight=1
|
||||
BooWeight=
|
||||
GoodWeight=1
|
||||
GreatWeight=28
|
||||
PerfectWeight=36
|
||||
MarvelousWeight=30
|
||||
|
||||
[Skill7]
|
||||
MissCum=0.01
|
||||
BooCum=0.02
|
||||
GoodCum=0.10
|
||||
GreatCum=0.3
|
||||
PerfectCum=0.6
|
||||
MarvelousCum=1
|
||||
MissWeight=
|
||||
BooWeight=
|
||||
GoodWeight=1
|
||||
GreatWeight=26
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=40
|
||||
|
||||
[Skill8]
|
||||
MissCum=0.01
|
||||
BooCum=0.01
|
||||
GoodCum=0.05
|
||||
GreatCum=0.25
|
||||
PerfectCum=0.5
|
||||
MarvelousCum=1
|
||||
MissWeight=
|
||||
BooWeight=
|
||||
GoodWeight=2
|
||||
GreatWeight=18
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=50
|
||||
|
||||
[Skill9]
|
||||
MissCum=0
|
||||
BooCum=0
|
||||
GoodCum=0
|
||||
GreatCum=0.2
|
||||
PerfectCum=0.5
|
||||
MarvelousCum=1
|
||||
MissWeight=
|
||||
BooWeight=
|
||||
GoodWeight=
|
||||
GreatWeight=10
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=60
|
||||
|
||||
[Skill10]
|
||||
MissCum=0
|
||||
BooCum=0
|
||||
GoodCum=0
|
||||
GreatCum=0
|
||||
PerfectCum=0.3
|
||||
MarvelousCum=1
|
||||
MissWeight=
|
||||
BooWeight=
|
||||
GoodWeight=
|
||||
GreatWeight=
|
||||
PerfectWeight=30
|
||||
MarvelousWeight=70
|
||||
|
||||
@@ -85,13 +85,11 @@ void GameState::Reset()
|
||||
m_StoredPlayerOptions[p].Init();
|
||||
}
|
||||
m_SongOptions.Init();
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
m_sPositioning[p] = "";
|
||||
SAFE_DELETE( m_pPosition );
|
||||
m_pPosition = new NoteFieldPositioning("Positioning.ini");
|
||||
|
||||
// apply defaults
|
||||
this->ApplyModifiers( PREFSMAN->m_sDefaultModifiers );
|
||||
for( p=0; p<NUM_PLAYERS; p++ )
|
||||
ApplyModifiers( (PlayerNumber)p, PREFSMAN->m_sDefaultModifiers );
|
||||
|
||||
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[p].FromString( sModifiers );
|
||||
m_PlayerOptions[pn].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
|
||||
@@ -510,12 +475,10 @@ void GameState::RemoveAllInventory()
|
||||
void GameState::RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn )
|
||||
{
|
||||
// rebuild player options
|
||||
PlayerOptions po = GAMESTATE->m_StoredPlayerOptions[pn];
|
||||
PlayerOptions po = m_StoredPlayerOptions[pn];
|
||||
for( int s=0; s<NUM_INVENTORY_SLOTS; s++ )
|
||||
{
|
||||
po.FromString( m_ActiveAttacks[pn][s].sModifier );
|
||||
}
|
||||
GAMESTATE->m_PlayerOptions[pn] = po;
|
||||
m_PlayerOptions[pn] = po;
|
||||
}
|
||||
|
||||
int GameState::GetSumOfActiveAttackLevels( PlayerNumber pn )
|
||||
|
||||
@@ -150,8 +150,7 @@ public:
|
||||
SongOptions m_SongOptions;
|
||||
SongOptions m_StoredSongOptions;
|
||||
|
||||
void ApplyModifiers( CString sModifiers );
|
||||
CString GetModifiers();
|
||||
void ApplyModifiers( PlayerNumber pn, CString sModifiers );
|
||||
void StoreSelectedOptions();
|
||||
void RestoreSelectedOptions();
|
||||
|
||||
@@ -175,7 +174,7 @@ public:
|
||||
// used in PLAY_MODE_BATTLE
|
||||
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 RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn );
|
||||
void RemoveAllActiveAttacks(); // called on end of song
|
||||
@@ -202,7 +201,6 @@ public:
|
||||
//
|
||||
// Arrow positioning
|
||||
//
|
||||
CString m_sPositioning[NUM_PLAYERS]; /* The current positioning mode, or empty to use the normal positions. */
|
||||
NoteFieldPositioning *m_pPosition;
|
||||
};
|
||||
|
||||
|
||||
@@ -24,9 +24,11 @@
|
||||
#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_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 };
|
||||
|
||||
#define ITEM_USE_PROBABILITY (1.f/ITEM_USE_RATE_SECONDS)
|
||||
|
||||
struct Item
|
||||
{
|
||||
@@ -52,6 +54,7 @@ void ReloadItems()
|
||||
|
||||
Inventory::Inventory()
|
||||
{
|
||||
ITEM_USE_RATE_SECONDS.Refresh();
|
||||
}
|
||||
|
||||
void Inventory::Load( PlayerNumber pn )
|
||||
@@ -114,18 +117,15 @@ void Inventory::Update( float fDelta )
|
||||
if( GAMESTATE->m_PlayerController[m_PlayerNumber] != PC_HUMAN &&
|
||||
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 iThisSecond = (int)RageTimer::GetTimeSinceStart();
|
||||
if( iLastSecond != iThisSecond )
|
||||
{
|
||||
int iSlotToConsider = rand()%NUM_INVENTORY_SLOTS;
|
||||
bool bTimeToUse = (rand()%6)==0;
|
||||
if( !GAMESTATE->m_Inventory[m_PlayerNumber][iSlotToConsider].IsBlank() &&
|
||||
bTimeToUse )
|
||||
{
|
||||
UseItem( iSlotToConsider );
|
||||
}
|
||||
for( int s=0; s<NUM_INVENTORY_SLOTS; s++ )
|
||||
if( !GAMESTATE->m_Inventory[m_PlayerNumber][s].IsBlank() )
|
||||
if( randomf(0,1) < ITEM_USE_PROBABILITY )
|
||||
UseItem( s );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,13 @@ void NoteField::Load( NoteData* pNoteData, PlayerNumber pn, int iFirstPixelToDra
|
||||
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 )
|
||||
{
|
||||
m_rectMarkerBar.Update( fDeltaTime );
|
||||
|
||||
@@ -32,8 +32,9 @@ public:
|
||||
virtual void Update( float fDeltaTime );
|
||||
virtual void DrawPrimitives();
|
||||
|
||||
void Load( NoteData* pNoteData, PlayerNumber pn, int iFirstPixelToDraw, int iLastPixelToDraw );
|
||||
void RemoveTapNoteRow( int iIndex );
|
||||
void Load( NoteData* pNoteData, PlayerNumber pn, int iFirstPixelToDraw, int iLastPixelToDraw );
|
||||
void ReloadNoteSkin();
|
||||
void RemoveTapNoteRow( int iIndex );
|
||||
|
||||
vector<bool> m_bIsHoldingHoldNote; // hack: Need this to know when to "light up" the center of hold notes
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ void NoteFieldPositioning::Load(PlayerNumber pn)
|
||||
}
|
||||
|
||||
/* 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)
|
||||
return; /* No, only use the style table settings. */
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "RageException.h"
|
||||
#include "GameState.h"
|
||||
#include "GameDef.h"
|
||||
#include "IniFile.h"
|
||||
#include "StyleInput.h"
|
||||
#include "StyleDef.h"
|
||||
#include "RageUtil.h"
|
||||
@@ -30,64 +29,41 @@ const CString NOTESKINS_DIR = "NoteSkins/";
|
||||
|
||||
NoteSkinManager::NoteSkinManager()
|
||||
{
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
{
|
||||
m_pIniMetrics[p] = new IniFile;
|
||||
SwitchNoteSkin( (PlayerNumber)p, BASE_NOTESKIN_NAME );
|
||||
}
|
||||
}
|
||||
|
||||
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 + "/";
|
||||
GetDirListing( sBaseSkinFolder + "*", AddTo, true );
|
||||
CStringArray asNoteSkinNames;
|
||||
GetDirListing( sBaseSkinFolder + "*", asNoteSkinNames, true );
|
||||
|
||||
int i;
|
||||
|
||||
// strip out "CVS"
|
||||
for( int i=AddTo.size()-1; i>=0; i-- )
|
||||
if( 0 == stricmp("cvs", AddTo[i]) )
|
||||
AddTo.erase( AddTo.begin()+i, AddTo.begin()+i+1 );
|
||||
}
|
||||
for( i=asNoteSkinNames.size()-1; i>=0; i-- )
|
||||
if( 0 == stricmp("cvs", asNoteSkinNames[i]) )
|
||||
asNoteSkinNames.erase( asNoteSkinNames.begin()+i, asNoteSkinNames.begin()+i+1 );
|
||||
|
||||
void NoteSkinManager::GetNoteSkinNames( CStringArray &AddTo ) const
|
||||
{
|
||||
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) )
|
||||
m_mapNameToData.clear();
|
||||
for( i=0; i<asNoteSkinNames.size(); i++ )
|
||||
{
|
||||
CStringArray as;
|
||||
GetNoteSkinNames( as );
|
||||
ASSERT( !as.empty() );
|
||||
|
||||
/* Prefer "default" if it exists. */
|
||||
sNewNoteSkin = as[0];
|
||||
for(unsigned i = 0; i < as.size(); ++i)
|
||||
if(!as[i].CompareNoCase("default")) sNewNoteSkin = "default";
|
||||
CString sName = asNoteSkinNames[i];
|
||||
sName.MakeLower();
|
||||
m_mapNameToData[sName] = NoteSkinData();
|
||||
LoadNoteSkinData( sName, m_mapNameToData[sName] );
|
||||
}
|
||||
}
|
||||
|
||||
m_sCurNoteSkinName[pn] = sNewNoteSkin;
|
||||
|
||||
m_pIniMetrics[pn]->Reset();
|
||||
void NoteSkinManager::LoadNoteSkinData( CString sNoteSkinName, NoteSkinData& data_out )
|
||||
{
|
||||
data_out.sName = sNoteSkinName;
|
||||
data_out.metrics.Reset();
|
||||
|
||||
/* Read only the default keys from the default noteskin. */
|
||||
IniFile defaults;
|
||||
@@ -95,11 +71,40 @@ void NoteSkinManager::SwitchNoteSkin( PlayerNumber pn, CString sNewNoteSkin )
|
||||
defaults.ReadFile();
|
||||
const IniFile::key *def = defaults.GetKey("NoteDisplay");
|
||||
if(def)
|
||||
m_pIniMetrics[pn]->SetValue("NoteDisplay", *def);
|
||||
data_out.metrics.SetValue("NoteDisplay", *def);
|
||||
|
||||
/* Read the active theme. */
|
||||
m_pIniMetrics[pn]->SetPath( GetNoteSkinDir(sNewNoteSkin)+"metrics.ini" );
|
||||
m_pIniMetrics[pn]->ReadFile();
|
||||
data_out.metrics.SetPath( GetNoteSkinDir(sNoteSkinName)+"metrics.ini" );
|
||||
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 )
|
||||
@@ -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 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;
|
||||
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'",
|
||||
sButtonName.GetString(), sValue.GetString(), sValue.GetString() );
|
||||
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 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
|
||||
return ret;
|
||||
ret = GetPathTo( BASE_NOTESKIN_NAME, sButtonName, sFileName);
|
||||
@@ -180,7 +189,7 @@ CString NoteSkinManager::GetPathTo( PlayerNumber pn, CString sButtonName, CStrin
|
||||
if( ret.empty() )
|
||||
RageException::Throw( "The NoteSkin element '%s %s' could not be found in '%s' or '%s'.",
|
||||
sButtonName.GetString(), sFileName.GetString(),
|
||||
GetNoteSkinDir(sCurNoteSkinName).GetString(),
|
||||
GetNoteSkinDir(sNoteSkinName).GetString(),
|
||||
GetNoteSkinDir(BASE_NOTESKIN_NAME).GetString() );
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
#include "RageTypes.h"
|
||||
#include "Game.h"
|
||||
#include "PlayerNumber.h"
|
||||
#include "IniFile.h"
|
||||
#include <map>
|
||||
|
||||
class IniFile;
|
||||
|
||||
class NoteSkinManager
|
||||
{
|
||||
@@ -24,11 +25,10 @@ public:
|
||||
NoteSkinManager();
|
||||
~NoteSkinManager();
|
||||
|
||||
void GetNoteSkinNames( Game game, CStringArray &AddTo ) const;
|
||||
void GetNoteSkinNames( CStringArray &AddTo ) const; // looks up current Game in GAMESTATE
|
||||
bool DoesNoteSkinExist( CString sSkinName ) const; // looks up current Game in GAMESTATE
|
||||
void SwitchNoteSkin( PlayerNumber pn, CString sNewNoteSkin ); // looks up current Game in GAMESTATE
|
||||
CString GetCurNoteSkinName( PlayerNumber pn ) const { return m_sCurNoteSkinName[pn]; };
|
||||
void RefreshNoteSkinData( Game game );
|
||||
void GetNoteSkinNames( Game game, CStringArray &AddTo );
|
||||
void GetNoteSkinNames( CStringArray &AddTo ); // looks up current Game in GAMESTATE
|
||||
bool DoesNoteSkinExist( CString sSkinName ); // looks up current Game in GAMESTATE
|
||||
|
||||
CString GetPathTo( PlayerNumber pn, int col, CString sFileName );
|
||||
CString GetPathTo( PlayerNumber pn, CString sButtonName, CString sFileName );
|
||||
@@ -42,13 +42,17 @@ public:
|
||||
|
||||
static CString NoteSkinManager::ColToButtonName(int col);
|
||||
|
||||
protected:
|
||||
CString GetNoteSkinDir( CString sSkinName );
|
||||
|
||||
CString m_sCurNoteSkinName[NUM_PLAYERS];
|
||||
IniFile* m_pIniMetrics[NUM_PLAYERS];
|
||||
unsigned m_uHashForCurThemeMetrics[NUM_PLAYERS];
|
||||
unsigned m_uHashForBaseThemeMetrics[NUM_PLAYERS];
|
||||
protected:
|
||||
|
||||
struct NoteSkinData
|
||||
{
|
||||
CString sName;
|
||||
IniFile metrics;
|
||||
};
|
||||
void LoadNoteSkinData( CString sNoteSkinName, NoteSkinData& data_out );
|
||||
map<CString,NoteSkinData> m_mapNameToData;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -180,6 +180,8 @@ void Player::Load( PlayerNumber pn, NoteData* pNoteData, LifeMeter* pLM, ScoreDi
|
||||
m_GrayArrowRow.SetZoom( 0.5f );
|
||||
m_GhostArrowRow.SetZoom( 0.5f );
|
||||
}
|
||||
|
||||
m_sLastSeenNoteSkin = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_sNoteSkin;
|
||||
}
|
||||
|
||||
void Player::Update( float fDeltaTime )
|
||||
@@ -276,6 +278,12 @@ void Player::Update( float fDeltaTime )
|
||||
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 );
|
||||
}
|
||||
|
||||
@@ -416,7 +424,8 @@ void Player::Step( int col )
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
score=TNS_NONE;
|
||||
score = TNS_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
if( score==TNS_MARVELOUS && !PREFSMAN->m_bMarvelousTiming )
|
||||
@@ -576,14 +585,14 @@ void Player::HandleTapRowScore( unsigned row )
|
||||
ASSERT(iNumTapsInRow > 0);
|
||||
|
||||
bool NoCheating = true;
|
||||
/*#ifdef DEBUG
|
||||
bool NoCheating = false;
|
||||
#endif //DEBUG*/
|
||||
#ifdef DEBUG
|
||||
NoCheating = false;
|
||||
#endif
|
||||
|
||||
if(GAMESTATE->m_bDemonstrationOrJukebox)
|
||||
NoCheating = false;
|
||||
// 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;
|
||||
|
||||
if(m_pScoreKeeper)
|
||||
|
||||
@@ -85,6 +85,8 @@ protected:
|
||||
ScoreDisplay* m_pScore;
|
||||
ScoreKeeper* m_pScoreKeeper;
|
||||
Inventory* m_pInventory;
|
||||
|
||||
CString m_sLastSeenNoteSkin;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+22
-11
@@ -20,15 +20,19 @@
|
||||
|
||||
struct TapScoreDistribution
|
||||
{
|
||||
float fCumulativeProbability[NUM_TAP_NOTE_SCORES];
|
||||
float fPercent[NUM_TAP_NOTE_SCORES];
|
||||
|
||||
TapNoteScore GetTapNoteScore()
|
||||
{
|
||||
float fRand = randomf(0,1);
|
||||
for( int i=TNS_MISS; i<=TNS_MARVELOUS; i++ )
|
||||
if( fRand <= fCumulativeProbability[i] )
|
||||
float fCumulativePercent = 0;
|
||||
for( int i=0; i<=TNS_MARVELOUS; i++ )
|
||||
{
|
||||
fCumulativePercent += fPercent[i];
|
||||
if( fRand <= fCumulativePercent )
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -50,13 +54,20 @@ void PlayerAI::InitFromDisk()
|
||||
RageException::Throw( "AI.ini: '%s' doesn't exist.", sKey.GetString() );
|
||||
|
||||
TapScoreDistribution& dist = g_Distributions[i];
|
||||
dist.fCumulativeProbability[TNS_NONE] = 0;
|
||||
ini.GetValueF( sKey, "MissCum", dist.fCumulativeProbability[TNS_MISS] );
|
||||
ini.GetValueF( sKey, "BooCum", dist.fCumulativeProbability[TNS_BOO] );
|
||||
ini.GetValueF( sKey, "GoodCum", dist.fCumulativeProbability[TNS_GOOD] );
|
||||
ini.GetValueF( sKey, "GreatCum", dist.fCumulativeProbability[TNS_GREAT] );
|
||||
ini.GetValueF( sKey, "PerfectCum", dist.fCumulativeProbability[TNS_PERFECT] );
|
||||
dist.fCumulativeProbability[TNS_MARVELOUS] = 1;
|
||||
dist.fPercent[TNS_NONE] = 0;
|
||||
ini.GetValueF( sKey, "MissWeight", dist.fPercent[TNS_MISS] );
|
||||
ini.GetValueF( sKey, "BooWeight", dist.fPercent[TNS_BOO] );
|
||||
ini.GetValueF( sKey, "GoodWeight", dist.fPercent[TNS_GOOD] );
|
||||
ini.GetValueF( sKey, "GreatWeight", dist.fPercent[TNS_GREAT] );
|
||||
ini.GetValueF( sKey, "PerfectWeight", dist.fPercent[TNS_PERFECT] );
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "GameState.h"
|
||||
#include "NoteFieldPositioning.h"
|
||||
#include "NoteSkinManager.h"
|
||||
|
||||
void PlayerOptions::Init()
|
||||
{
|
||||
@@ -33,6 +34,9 @@ void PlayerOptions::Init()
|
||||
m_bTimingAssist = false;
|
||||
m_fPerspectiveTilt = 0;
|
||||
m_bTimeSpacing = false;
|
||||
m_sPositioning = ""; // "null"
|
||||
m_sNoteSkin = "default";
|
||||
|
||||
}
|
||||
|
||||
void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds )
|
||||
@@ -132,6 +136,11 @@ CString PlayerOptions::GetString()
|
||||
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 )
|
||||
sReturn.erase( sReturn.GetLength()-2 ); // delete the trailing ", "
|
||||
return sReturn;
|
||||
@@ -196,6 +205,10 @@ void PlayerOptions::FromString( CString sOptions )
|
||||
else if( sBit == "timingassist")m_bTimingAssist = true;
|
||||
else if( sBit == "incoming" ) 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,8 @@ struct PlayerOptions
|
||||
bool m_bTimingAssist;
|
||||
float m_fPerspectiveTilt; // -1 = near, 0 = overhead, +1 = space
|
||||
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 NextEffect();
|
||||
|
||||
@@ -351,8 +351,8 @@ retry:
|
||||
PixFmtMasks[pixfmt].masks[0], PixFmtMasks[pixfmt].masks[1],
|
||||
PixFmtMasks[pixfmt].masks[2], PixFmtMasks[pixfmt].masks[3]);
|
||||
|
||||
//SM_SDL_OrderedDither(img, dst);
|
||||
SM_SDL_ErrorDiffusionDither(img, dst);
|
||||
SM_SDL_OrderedDither(img, dst);
|
||||
//SM_SDL_ErrorDiffusionDither(img, dst);
|
||||
SDL_FreeSurface(img);
|
||||
img = dst;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "RageLog.h"
|
||||
#include "GameState.h"
|
||||
#include "ThemeManager.h"
|
||||
#include "RageTextureManager.h"
|
||||
|
||||
ScoreDisplayBattle::ScoreDisplayBattle()
|
||||
{
|
||||
@@ -36,6 +37,11 @@ ScoreDisplayBattle::ScoreDisplayBattle()
|
||||
m_ItemIcon[i].StopAnimating();
|
||||
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 )
|
||||
|
||||
@@ -241,7 +241,7 @@ ScreenEdit::ScreenEdit() : Screen("ScreenEdit")
|
||||
|
||||
GAMESTATE->m_PlayerOptions[PLAYER_1].m_fScrollSpeed = 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") );
|
||||
|
||||
@@ -272,7 +272,7 @@ ScreenEdit::ScreenEdit() : Screen("ScreenEdit")
|
||||
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, ¬eData, NULL, NULL, NULL, NULL );
|
||||
GAMESTATE->m_PlayerController[PLAYER_1] = PC_HUMAN;
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include "NoteFieldPositioning.h"
|
||||
#include "LyricsLoader.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
|
||||
|
||||
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
|
||||
@@ -563,8 +589,7 @@ void ScreenGameplay::LoadNextSong()
|
||||
m_pScoreKeeper[p]->OnNextSong( GAMESTATE->GetCourseSongIndex(), GAMESTATE->m_pCurNotes[p] );
|
||||
|
||||
// Put courses options into effect.
|
||||
GAMESTATE->m_PlayerOptions[p].FromString( m_asModifiersQueue[p][iPlaySongIndex] );
|
||||
GAMESTATE->m_SongOptions.FromString( m_asModifiersQueue[p][iPlaySongIndex] );
|
||||
GAMESTATE->ApplyModifiers( (PlayerNumber)p, m_asModifiersQueue[p][iPlaySongIndex] );
|
||||
|
||||
m_textPlayerOptions[p].SetText( GAMESTATE->m_PlayerOptions[p].GetString() );
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ void ScreenPlayerOptions::ImportOptions()
|
||||
m_iSelectedOption[p][PO_NOTE_SKIN] = -1;
|
||||
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;
|
||||
break;
|
||||
@@ -177,7 +177,7 @@ void ScreenPlayerOptions::ImportOptions()
|
||||
{
|
||||
vector<CString> &choices = m_OptionRow[PO_PERSPECTIVE].choices;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ void ScreenPlayerOptions::ExportOptions()
|
||||
|
||||
int iSelectedSkin = m_iSelectedOption[p][PO_NOTE_SKIN];
|
||||
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);
|
||||
@@ -241,7 +241,7 @@ void ScreenPlayerOptions::ExportOptions()
|
||||
if(m_iSelectedOption[p][PO_PERSPECTIVE] > 2)
|
||||
{
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,8 +53,6 @@ ScreenRaveOptions::ScreenRaveOptions() :
|
||||
g_RaveOptionsLines,
|
||||
bComputerPlayersPresent ? 3 : 1,
|
||||
false, false );
|
||||
|
||||
SOUNDMAN->PlayMusic( THEME->GetPathToS("ScreenMachineOptions music") );
|
||||
}
|
||||
|
||||
void ScreenRaveOptions::ImportOptions()
|
||||
|
||||
@@ -73,7 +73,7 @@ ScreenSelectGroup::ScreenSelectGroup() : Screen("ScreenSelectGroup")
|
||||
}
|
||||
|
||||
// Add all group names to a map.
|
||||
std::map<CString, CString> mapGroupNames;
|
||||
map<CString, CString> mapGroupNames;
|
||||
for( i=0; i<aAllSongs.size(); i++ )
|
||||
{
|
||||
const CString& sGroupName = aAllSongs[i]->m_sGroupName;
|
||||
@@ -81,9 +81,9 @@ ScreenSelectGroup::ScreenSelectGroup() : Screen("ScreenSelectGroup")
|
||||
}
|
||||
|
||||
// copy group names into a vector
|
||||
std::vector<CString> asGroupNames;
|
||||
vector<CString> asGroupNames;
|
||||
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 );
|
||||
|
||||
// Add songs to the MusicList.
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
bool DoesThemeExist( CString sThemeName );
|
||||
void SwitchTheme( CString sThemeName );
|
||||
CString GetCurThemeName() { return m_sCurThemeName; };
|
||||
CString GetCurThemeDir() { return GetThemeDirFromName(m_sCurThemeName); };
|
||||
void NextTheme();
|
||||
|
||||
CString GetPathTo( ElementCategory category, CString sFileName, bool bOptional=false );
|
||||
|
||||
Reference in New Issue
Block a user