Song Attacks modifier (course-style scripted mods in regular single play)

This commit is contained in:
Mike Hawkins
2008-05-30 01:09:00 +00:00
parent 316f9b511f
commit 25b13dfcdf
8 changed files with 143 additions and 65 deletions
@@ -623,6 +623,7 @@ Silent=Silent
Skip=Skip Skip=Skip
Skippy=Skippy Skippy=Skippy
Slow=Slow Slow=Slow
SongAttacks=Song Attacks
Song BGAnimation=Song BGAnimation Song BGAnimation=Song BGAnimation
Song Bitmap=Song Bitmap Song Bitmap=Song Bitmap
Song Movie=Song Movie Song Movie=Song Movie
+3 -2
View File
@@ -3669,10 +3669,11 @@ Mines,1="mod,nomines;name,Off"
Mines,2="name,On" Mines,2="name,On"
Mines,3="mod,mines;name,Add" Mines,3="mod,mines;name,Add"
Mines,4="mod,attackmines;name,AttackMines" Mines,4="mod,attackmines;name,AttackMines"
Attacks="2" Attacks="3"
AttacksDefault="mod,no randomattacks" AttacksDefault="mod,no randomattacks,no songattacks"
Attacks,1="name,Off" Attacks,1="name,Off"
Attacks,2="mod,randomattacks;name,RandomAttacks" Attacks,2="mod,randomattacks;name,RandomAttacks"
Attacks,3="mod,songattacks;name,SongAttacks"
Hide="3" Hide="3"
HideDefault="mod,no dark,no blind" HideDefault="mod,no dark,no blind"
Hide,1="name,Off" Hide,1="name,Off"
+72 -26
View File
@@ -21,7 +21,7 @@ static void LoadFromSMTokens(
RString sRadarValues, RString sRadarValues,
RString sNoteData, RString sNoteData,
Steps &out Steps &out
) )
{ {
out.SetSavedToDisk( true ); // we're loading from disk, so this is by definintion already saved out.SetSavedToDisk( true ); // we're loading from disk, so this is by definintion already saved
@@ -30,7 +30,7 @@ static void LoadFromSMTokens(
Trim( sDifficulty ); Trim( sDifficulty );
Trim( sNoteData ); Trim( sNoteData );
// LOG->Trace( "Steps::LoadFromSMTokens()" ); // LOG->Trace( "Steps::LoadFromSMTokens()" );
out.m_StepsType = GameManager::StringToStepsType( sStepsType ); out.m_StepsType = GameManager::StringToStepsType( sStepsType );
out.SetDescription( sDescription ); out.SetDescription( sDescription );
@@ -119,7 +119,7 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds ); StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds );
// LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); // LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
out.AddStopSegment( new_seg ); out.AddStopSegment( new_seg );
} }
@@ -465,6 +465,52 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache
split( sParams[1], ",", out.m_vsKeysoundFile ); split( sParams[1], ",", out.m_vsKeysoundFile );
} }
// Attacks loaded from file
else if( sValueName=="ATTACKS" )
{
// Build the RString vector here so we can write it to file again later
for( unsigned s=1; s < sParams.params.size(); ++s )
out.m_sAttackString.push_back( sParams[s] );
Attack attack;
float end = -9999;
for( unsigned j=1; j < sParams.params.size(); ++j )
{
vector<RString> sBits;
split( sParams[j], "=", sBits, false );
// Need an identifer and a value for this to work
if( sBits.size() < 2 )
continue;
TrimLeft( sBits[0] );
TrimRight( sBits[0] );
if( !sBits[0].CompareNoCase("TIME") )
attack.fStartSecond = strtof( sBits[1], NULL );
else if( !sBits[0].CompareNoCase("LEN") )
attack.fSecsRemaining = strtof( sBits[1], NULL );
else if( !sBits[0].CompareNoCase("END") )
end = strtof( sBits[1], NULL );
else if( !sBits[0].CompareNoCase("MODS") )
{
attack.sModifiers = sBits[1];
if( end != -9999 )
{
attack.fSecsRemaining = end - attack.fStartSecond;
end = -9999;
}
if( attack.fSecsRemaining < 0.0f )
attack.fSecsRemaining = 0.0f;
out.m_Attacks.push_back( attack );
}
}
}
else if( sValueName=="NOTES" || sValueName=="NOTES2" ) else if( sValueName=="NOTES" || sValueName=="NOTES2" )
{ {
if( iNumParams < 7 ) if( iNumParams < 7 )
@@ -678,26 +724,26 @@ void SMLoader::TidyUpData( Song &song, bool bFromCache )
} }
/* /*
* (c) 2001-2004 Chris Danford, Glenn Maynard * (c) 2001-2004 Chris Danford, Glenn Maynard
* All rights reserved. * All rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the * copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to * 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 * whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of * copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this * the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation. * permission notice appear in supporting documentation.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS * 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 * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * 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 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
+11
View File
@@ -168,6 +168,17 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
f.Write( "," ); f.Write( "," );
} }
f.PutLine( ";" ); f.PutLine( ";" );
f.Write( "#ATTACKS:" );
for( unsigned a=0; a < out.m_sAttackString.size(); a++ )
{
RString sData = out.m_sAttackString[a];
f.Write( ssprintf( "%s", sData.c_str() ) );
if( a != (out.m_sAttackString.size() - 1) )
f.Write( ":" ); // Not the end, so write a divider ':'
}
f.PutLine( ";" );
} }
static RString JoinLineList( vector<RString> &lines ) static RString JoinLineList( vector<RString> &lines )
+5
View File
@@ -28,6 +28,7 @@ void PlayerOptions::Init()
m_fBlind = 0; m_SpeedfBlind = 1.0f; m_fBlind = 0; m_SpeedfBlind = 1.0f;
m_fCover = 0; m_SpeedfCover = 1.0f; m_fCover = 0; m_SpeedfCover = 1.0f;
m_fRandAttack = 0; m_SpeedfRandAttack = 1.0f; m_fRandAttack = 0; m_SpeedfRandAttack = 1.0f;
m_fSongAttack = 0; m_SpeedfSongAttack = 1.0f;
m_bSetTiltOrSkew = false; m_bSetTiltOrSkew = false;
m_fPerspectiveTilt = 0; m_SpeedfPerspectiveTilt = 1.0f; m_fPerspectiveTilt = 0; m_SpeedfPerspectiveTilt = 1.0f;
m_fSkew = 0; m_SpeedfSkew = 1.0f; m_fSkew = 0; m_SpeedfSkew = 1.0f;
@@ -63,6 +64,7 @@ void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds )
APPROACH( fBlind ); APPROACH( fBlind );
APPROACH( fCover ); APPROACH( fCover );
APPROACH( fRandAttack ); APPROACH( fRandAttack );
APPROACH( fSongAttack );
APPROACH( fPerspectiveTilt ); APPROACH( fPerspectiveTilt );
APPROACH( fSkew ); APPROACH( fSkew );
APPROACH( fPassmark ); APPROACH( fPassmark );
@@ -166,6 +168,7 @@ void PlayerOptions::GetMods( vector<RString> &AddTo, bool bForceNoteSkin ) const
AddPart( AddTo, m_fCover, "Cover" ); AddPart( AddTo, m_fCover, "Cover" );
AddPart( AddTo, m_fRandAttack, "RandomAttacks" ); AddPart( AddTo, m_fRandAttack, "RandomAttacks" );
AddPart( AddTo, m_fSongAttack, "SongAttacks" );
AddPart( AddTo, m_fPassmark, "Passmark" ); AddPart( AddTo, m_fPassmark, "Passmark" );
@@ -380,6 +383,7 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
else if( sBit == "blind" ) SET_FLOAT( fBlind ) else if( sBit == "blind" ) SET_FLOAT( fBlind )
else if( sBit == "cover" ) SET_FLOAT( fCover ) else if( sBit == "cover" ) SET_FLOAT( fCover )
else if( sBit == "randomattacks" ) SET_FLOAT( fRandAttack ) else if( sBit == "randomattacks" ) SET_FLOAT( fRandAttack )
else if( sBit == "songattacks" ) SET_FLOAT( fSongAttack )
else if( sBit == "passmark" ) SET_FLOAT( fPassmark ) else if( sBit == "passmark" ) SET_FLOAT( fPassmark )
else if( sBit == "overhead" ) { m_bSetTiltOrSkew = true; m_fSkew = 0; m_fPerspectiveTilt = 0; m_SpeedfSkew = m_SpeedfPerspectiveTilt = speed; } else if( sBit == "overhead" ) { m_bSetTiltOrSkew = true; m_fSkew = 0; m_fPerspectiveTilt = 0; m_SpeedfSkew = m_SpeedfPerspectiveTilt = speed; }
else if( sBit == "incoming" ) { m_bSetTiltOrSkew = true; m_fSkew = level; m_fPerspectiveTilt = -level; m_SpeedfSkew = m_SpeedfPerspectiveTilt = speed; } else if( sBit == "incoming" ) { m_bSetTiltOrSkew = true; m_fSkew = level; m_fPerspectiveTilt = -level; m_SpeedfSkew = m_SpeedfPerspectiveTilt = speed; }
@@ -619,6 +623,7 @@ bool PlayerOptions::operator==( const PlayerOptions &other ) const
COMPARE(m_fBlind); COMPARE(m_fBlind);
COMPARE(m_fCover); COMPARE(m_fCover);
COMPARE(m_fRandAttack); COMPARE(m_fRandAttack);
COMPARE(m_fSongAttack);
COMPARE(m_fPerspectiveTilt); COMPARE(m_fPerspectiveTilt);
COMPARE(m_fSkew); COMPARE(m_fSkew);
COMPARE(m_sNoteSkin); COMPARE(m_sNoteSkin);
+1
View File
@@ -134,6 +134,7 @@ public:
float m_fBlind, m_SpeedfBlind; float m_fBlind, m_SpeedfBlind;
float m_fCover, m_SpeedfCover; // hide the background per-player--can't think of a good name float m_fCover, m_SpeedfCover; // hide the background per-player--can't think of a good name
float m_fRandAttack, m_SpeedfRandAttack; float m_fRandAttack, m_SpeedfRandAttack;
float m_fSongAttack, m_SpeedfSongAttack;
bool m_bSetTiltOrSkew; // true if the tilt or skew was set by FromString bool m_bSetTiltOrSkew; // true if the tilt or skew was set by FromString
float m_fPerspectiveTilt, m_SpeedfPerspectiveTilt; // -1 = near, 0 = overhead, +1 = space float m_fPerspectiveTilt, m_SpeedfPerspectiveTilt; // -1 = near, 0 = overhead, +1 = space
float m_fSkew, m_SpeedfSkew; // 0 = vanish point is in center of player, 1 = vanish point is in center of screen float m_fSkew, m_SpeedfSkew; // 0 = vanish point is in center of player, 1 = vanish point is in center of screen
+8
View File
@@ -830,10 +830,18 @@ void ScreenGameplay::InitSongQueues()
Steps *pSteps = GAMESTATE->m_pCurSteps[ pi->GetStepsAndTrailIndex() ]; Steps *pSteps = GAMESTATE->m_pCurSteps[ pi->GetStepsAndTrailIndex() ];
pi->m_vpStepsQueue.push_back( pSteps ); pi->m_vpStepsQueue.push_back( pSteps );
if( pi->GetPlayerState()->m_PlayerOptions.GetCurrent().m_fSongAttack != 0 &&
GAMESTATE->m_pCurSong->m_Attacks.size() > 0 )
{
pi->m_asModifiersQueue.push_back( GAMESTATE->m_pCurSong->m_Attacks );
}
else
{
AttackArray aa; AttackArray aa;
pi->m_asModifiersQueue.push_back( aa ); pi->m_asModifiersQueue.push_back( aa );
} }
} }
}
if( GAMESTATE->m_bMultiplayer ) if( GAMESTATE->m_bMultiplayer )
{ {
+5
View File
@@ -3,6 +3,7 @@
#ifndef SONG_H #ifndef SONG_H
#define SONG_H #define SONG_H
#include "Attack.h"
#include "TimingData.h" #include "TimingData.h"
#include "Difficulty.h" #include "Difficulty.h"
#include "EnumHelper.h" #include "EnumHelper.h"
@@ -144,6 +145,9 @@ public:
RString m_sBackgroundFile; RString m_sBackgroundFile;
RString m_sCDTitleFile; RString m_sCDTitleFile;
AttackArray m_Attacks;
vector<RString> m_sAttackString;
RString GetMusicPath() const; RString GetMusicPath() const;
RString GetInstrumentTrackPath( InstrumentTrack it ) const; RString GetInstrumentTrackPath( InstrumentTrack it ) const;
RString GetBannerPath() const; RString GetBannerPath() const;
@@ -151,6 +155,7 @@ public:
RString GetBackgroundPath() const; RString GetBackgroundPath() const;
RString GetCDTitlePath() const; RString GetCDTitlePath() const;
/* For loading only: */ /* For loading only: */
bool m_bHasMusic, m_bHasBanner; bool m_bHasMusic, m_bHasBanner;