Random attacks modifier

This commit is contained in:
Mike Hawkins
2008-05-16 04:00:13 +00:00
parent b9c0288a2c
commit b3e11dcb94
10 changed files with 196 additions and 6 deletions
+73
View File
@@ -0,0 +1,73 @@
// File for specifying Random Attacks, used by the Random Attacks mod and Attack Mines mod.
// Only specify one modifier per attack.
//
// Sample lines:
//
// #ATTACK:drunk;
// #ATTACK:30% tornado;
// #ATTACK:-20% beat;
//
//
// Speed Mods
//
#ATTACK:0.5x;
#ATTACK:1x;
#ATTACK:1.5x;
#ATTACK:2x;
//
// Accel Mods
//
#ATTACK:boost;
#ATTACK:brake;
#ATTACK:wave;
#ATTACK:expand;
//
// Effect Mods
//
#ATTACK:drunk;
#ATTACK:dizzy;
#ATTACK:confusion;
#ATTACK:65% mini;
#ATTACK:20% flip;
#ATTACK:30% invert;
#ATTACK:30% tornado;
#ATTACK:tipsy;
#ATTACK:beat;
#ATTACK:bumpy;
//
// Appearance Mods
//
#ATTACK:50% hidden;
#ATTACK:50% sudden;
#ATTACK:30% blink;
//
// Hide Mods
//
#ATTACK:dark;
#ATTACK:blind;
//
// Transform Mods
//
#ATTACK:mines;
//
// Scroll
//
#ATTACK:30% reverse;
#ATTACK:reverse;
#ATTACK:centered;
//
// Perspective Mods
//
#ATTACK:hallway;
#ATTACK:space;
#ATTACK:incoming;
#ATTACK:overhead;
#ATTACK:distant;
@@ -277,6 +277,7 @@ Appearance=Appearance
Appearance Options=Change the theme, announcer, and other style options.
ArcadeOptionsNavigation=When using &oq;SM style&cq;, the Start button will take you to the next screen and Up/Down will switch option lines. When using &oq;Arcade style&cq;, the Start button will move the cursor to the next line and Up/Down will be ignored.
Assist=Assist
Attacks=Choose whether non-course attacks will appear during gameplay.
AttractSoundFrequency=Set to ALWAYS to play sound every during the attract screens. Set to N TIMES to play sounds every N attract sequences.
AutoAdjust=AutoAdjust
AutoMapOnJoyChange=&oq;ON&cq; will cause the game to automatically remap all the joysticks attached to your computer if the joysticks attached to your system are different than the last time you started the game. Auto mapping will override any manually defined mappings.
@@ -598,6 +599,7 @@ Press Start=Press Start
Quick=Quick
R.Vanish=R.Vanish
Random=Random
RandomAttacks=Random Attacks
RandomBG=Random Backgrounds
Random Movies=Random Movies
Ranking=Ranking
@@ -679,6 +681,7 @@ ArcadeOptionsNavigation=Options Navigation
Artist=Artist
Artist transliteration=Artist transliteration
Assist=Assist
Attacks=Attacks
AttractSoundFrequency=Attract Sound Frequency
AutoAdjust=Auto Adjust
AutoMapOnJoyChange=Auto Map On Joy Change
+11 -6
View File
@@ -3466,7 +3466,7 @@ NextScreen=ScreenPlayerOptionsNext()
PlayMusic=false
TimerSeconds=30
ShowStyleIcon=false
LineNames="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15"
LineNames="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16"
Line1="list,Speed"
Line2="list,Accel"
Line3="list,Effect"
@@ -3477,11 +3477,12 @@ Line7="list,Scroll"
Line8="list,NoteSkins"
Line9="list,Holds"
Line10="list,Mines"
Line11="list,Hide"
Line12="list,Persp"
Line13="list,ScoreDisplay"
Line14="list,Steps"
Line15="list,Characters"
Line11="list,Attacks"
Line12="list,Hide"
Line13="list,Persp"
Line14="list,ScoreDisplay"
Line15="list,Steps"
Line16="list,Characters"
[ScreenRaveOptions]
Fallback="ScreenOptions"
@@ -3680,6 +3681,10 @@ MinesDefault="mod,no nomines,no mines"
Mines,1="mod,nomines;name,Off"
Mines,2="name,On"
Mines,3="mod,mines;name,Add"
Attacks="2"
AttacksDefault="mod,no randomattacks"
Attacks,1="name,Off"
Attacks,2="mod,randomattacks;name,RandomAttacks"
Hide="3"
HideDefault="mod,no dark,no blind"
Hide,1="name,Off"
+5
View File
@@ -205,6 +205,11 @@ public:
float m_fLastHasteUpdateMusicSeconds;
float m_fAccumulatedHasteSeconds;
//
// Random Attacks & Attack Mines
//
vector<RString> m_RandomAttacks;
// used in PLAY_MODE_BATTLE
float m_fOpponentHealthPercent;
+39
View File
@@ -380,6 +380,8 @@ void Player::Init(
m_vbFretIsDown.resize( GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer );
FOREACH( bool, m_vbFretIsDown, b )
*b = false;
m_fActiveRandomAttackStart = -1.0f;
}
static bool NeedsTapJudging( const TapNote &tn )
@@ -596,6 +598,34 @@ void Player::Update( float fDeltaTime )
// if the Player doesn't show anything on the screen.
if( HasVisibleParts() )
{
//
// Random Attack Mod
//
if( m_pPlayerState->m_PlayerOptions.GetCurrent().m_fRandAttack )
{
float fCurrentGameTime = STATSMAN->m_CurStageStats.m_fGameplaySeconds;
// Should we hardcode this, or make it a preference/theme metric? ~ Mike
const float fAttackRunTime = 6.0f;
// Don't start until 1 seconds into game, minimum
if( fCurrentGameTime > 1.0f )
{
/* Update the attack if there are no others currently running.
* Note that we have a new one activate a little early; this is to have a bit
* of overlap rather than an abrupt change */
if( (fCurrentGameTime - m_fActiveRandomAttackStart) > (fAttackRunTime - 0.5f) )
{
m_fActiveRandomAttackStart = fCurrentGameTime;
Attack attRandomAttack;
attRandomAttack.sModifiers = ApplyRandomAttack();
attRandomAttack.fSecsRemaining = fAttackRunTime;
m_pPlayerState->LaunchAttack( attRandomAttack);
}
}
}
if( g_bEnableAttackSoundPlayback )
{
if( m_pPlayerState->m_bAttackBeganThisUpdate )
@@ -2807,6 +2837,15 @@ void Player::SetCombo( int iCombo, int iMisses )
this->HandleMessage( msg );
}
RString Player::ApplyRandomAttack()
{
if( GAMESTATE->m_RandomAttacks.size() < 1 )
return "";
int iAttackToUse = rand() % GAMESTATE->m_RandomAttacks.size();
return GAMESTATE->m_RandomAttacks[iAttackToUse];
}
// lua start
#include "LuaBinding.h"
+4
View File
@@ -130,6 +130,8 @@ protected:
int GetClosestNonEmptyRowDirectional( int iStartRow, int iMaxRowsAhead, bool bAllowGraded, bool bForward ) const;
int GetClosestNonEmptyRow( int iNoteRow, int iMaxRowsAhead, int iMaxRowsBehind, bool bAllowGraded ) const;
RString ApplyRandomAttack();
inline void HideNote( int col, int row )
{
NoteData::iterator iter = m_NoteData.FindTapNote( col, row );
@@ -179,6 +181,8 @@ protected:
RageSound m_soundAttackLaunch;
RageSound m_soundAttackEnding;
float m_fActiveRandomAttackStart;
vector<bool> m_vbFretIsDown;
vector<RageSound> m_vKeysounds;
+6
View File
@@ -27,6 +27,7 @@ void PlayerOptions::Init()
m_fDark = 0; m_SpeedfDark = 1.0f;
m_fBlind = 0; m_SpeedfBlind = 1.0f;
m_fCover = 0; m_SpeedfCover = 1.0f;
m_fRandAttack = 0; m_SpeedfRandAttack = 1.0f;
m_bSetTiltOrSkew = false;
m_fPerspectiveTilt = 0; m_SpeedfPerspectiveTilt = 1.0f;
m_fSkew = 0; m_SpeedfSkew = 1.0f;
@@ -61,6 +62,7 @@ void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds )
APPROACH( fDark );
APPROACH( fBlind );
APPROACH( fCover );
APPROACH( fRandAttack );
APPROACH( fPerspectiveTilt );
APPROACH( fSkew );
APPROACH( fPassmark );
@@ -163,6 +165,8 @@ void PlayerOptions::GetMods( vector<RString> &AddTo, bool bForceNoteSkin ) const
AddPart( AddTo, m_fBlind, "Blind" );
AddPart( AddTo, m_fCover, "Cover" );
AddPart( AddTo, m_fRandAttack, "RandomAttacks" );
AddPart( AddTo, m_fPassmark, "Passmark" );
AddPart( AddTo, m_fRandomSpeed, "RandomSpeed" );
@@ -373,6 +377,7 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
else if( sBit == "dark" ) SET_FLOAT( fDark )
else if( sBit == "blind" ) SET_FLOAT( fBlind )
else if( sBit == "cover" ) SET_FLOAT( fCover )
else if( sBit == "randomattacks" ) SET_FLOAT( fRandAttack )
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 == "incoming" ) { m_bSetTiltOrSkew = true; m_fSkew = level; m_fPerspectiveTilt = -level; m_SpeedfSkew = m_SpeedfPerspectiveTilt = speed; }
@@ -611,6 +616,7 @@ bool PlayerOptions::operator==( const PlayerOptions &other ) const
COMPARE(m_fDark);
COMPARE(m_fBlind);
COMPARE(m_fCover);
COMPARE(m_fRandAttack);
COMPARE(m_fPerspectiveTilt);
COMPARE(m_fSkew);
COMPARE(m_sNoteSkin);
+1
View File
@@ -125,6 +125,7 @@ public:
float m_fDark, m_SpeedfDark;
float m_fBlind, m_SpeedfBlind;
float m_fCover, m_SpeedfCover; // hide the background per-player--can't think of a good name
float m_fRandAttack, m_SpeedfRandAttack;
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_fSkew, m_SpeedfSkew; // 0 = vanish point is in center of player, 1 = vanish point is in center of screen
+53
View File
@@ -44,6 +44,8 @@ const RString COURSES_DIR = "/Courses/";
const RString ADDITIONAL_COURSES_DIR = "/AdditionalCourses/";
const RString EDIT_SUBDIR = "Edits/";
const RString ATTACK_FILE = "/Data/RandomAttacks.txt";
static const ThemeMetric<RageColor> EXTRA_COLOR ( "SongManager", "ExtraColor" );
static const ThemeMetric<int> EXTRA_COLOR_METER ( "SongManager", "ExtraColorMeter" );
static const ThemeMetric<bool> USE_PREFERRED_SORT_COLOR ( "SongManager", "UsePreferredSortColor" );
@@ -92,6 +94,7 @@ void SongManager::InitAll( LoadingWindow *ld )
InitSongsFromDisk( ld );
InitCoursesFromDisk( ld );
InitAutogenCourses();
InitRandomAttacks();
}
static LocalizedString RELOADING ( "SongManager", "Reloading..." );
@@ -798,6 +801,56 @@ void SongManager::InitAutogenCourses()
}
}
void SongManager::InitRandomAttacks()
{
GAMESTATE->m_RandomAttacks.clear();
if( !IsAFile(ATTACK_FILE) )
LOG->Trace( "File Data/RandomAttacks.txt was not found" );
else
{
MsdFile msd;
if( !msd.ReadFile( ATTACK_FILE, true ) )
LOG->Warn( "Error opening file '%s' for reading: %s.", ATTACK_FILE, msd.GetError().c_str() );
else
{
for( unsigned i=0; i<msd.GetNumValues(); i++ )
{
int iNumParams = msd.GetNumParams(i);
const MsdFile::value_t &sParams = msd.GetValue(i);
RString sType = sParams[0];
RString sAttack = sParams[1];
if( iNumParams > 2 )
{
LOG->Warn( "Got \"%s:%s\" tag with too many parameters", sType.c_str(), sAttack.c_str() );
continue;
}
if( stricmp(sType,"ATTACK") != 0 )
{
LOG->Warn( "Got \"%s:%s\" tag with wrong declaration", sType.c_str(), sAttack.c_str() );
continue;
}
// Check to make sure only one attack has been specified
// TODO: Allow combinations of mods
vector<RString> sAttackCheck;
split( sAttack, ",", sAttackCheck, false );
if( sAttackCheck.size() > 1 )
{
LOG->Warn( "Attack \"%s\" has more than one modifier; must only be one modifier specified", sAttack.c_str() );
continue;
}
GAMESTATE->m_RandomAttacks.push_back( sAttack );
}
}
}
}
void SongManager::FreeCourses()
{
for( unsigned i=0; i<m_pCourses.size(); i++ )
+1
View File
@@ -50,6 +50,7 @@ public:
void InitCoursesFromDisk( LoadingWindow *ld );
void InitAutogenCourses();
void InitRandomAttacks();
void FreeCourses();
void AddCourse( Course *pCourse ); // transfers ownership of pCourse
void DeleteCourse( Course *pCourse ); // transfers ownership of pCourse