Add nITG's new Move modifiers (#1411)

* Implemented NITG's MoveX/Y/Z modifiers

Added modifiers:
MoveX1-n: Moves a column in the x direction, 100% = move left one arrow size. 
MoveY1-n: Moves a column in the y direction
MoveZ1-n: Moves a column in the z direction.
This commit is contained in:
MrThatKid
2017-02-25 15:48:03 -08:00
committed by Colby Klein
parent 8f332653e1
commit 1c9227db22
7 changed files with 153 additions and 5 deletions
+3
View File
@@ -1161,6 +1161,9 @@
<Function name='MinTNSToHideNotes' /> <Function name='MinTNSToHideNotes' />
<Function name='Mirror'/> <Function name='Mirror'/>
<Function name='MMod'/> <Function name='MMod'/>
<Function name='MoveXn'/>
<Function name='MoveYn'/>
<Function name='MoveZn'/>
<Function name='MuteOnError'/> <Function name='MuteOnError'/>
<Function name='NoAttack'/> <Function name='NoAttack'/>
<Function name='NoFakes'/> <Function name='NoFakes'/>
+9
View File
@@ -3517,6 +3517,15 @@ save yourself some time, copy this for undocumented things:
If the optional second argument is passed, sets the speed at which the transition occurs.<br /> If the optional second argument is passed, sets the speed at which the transition occurs.<br />
MMods are not tweenable or settable on ScreenGameplay. Use XMods if you need such an effect. MMods are not tweenable or settable on ScreenGameplay. Use XMods if you need such an effect.
</Function> </Function>
<Function name='MoveXn' return= 'float, float' arguments='float value, float approach_speed'>
Use 1-16 in place of 'n' to move a specific column.
</Function>
<Function name='MoveYn' return= 'float, float' arguments='float value, float approach_speed'>
Use 1-16 in place of 'n' to move a specific column.
</Function>
<Function name='MoveZn' return= 'float, float' arguments='float value, float approach_speed'>
Use 1-16 in place of 'n' to move a specific column.
</Function>
<Function name='MuteOnError' return='bool' arguments='bool value'> </Function> <Function name='MuteOnError' return='bool' arguments='bool value'> </Function>
<Function name='NoAttack' return='float, float' arguments='float value, float approach_speed'> </Function> <Function name='NoAttack' return='float, float' arguments='float value, float approach_speed'> </Function>
<Function name='NoFakes' return='bool' arguments='bool value'> </Function> <Function name='NoFakes' return='bool' arguments='bool value'> </Function>
+27
View File
@@ -675,6 +675,33 @@ float ArrowEffects::ReceptorGetRotationY( const PlayerState* pPlayerState )
return fRotation; return fRotation;
} }
float ArrowEffects::GetMoveX(int iCol)
{
const float* fMoves = curr_options->m_fMovesX;
float f = 0;
if( fMoves[iCol] != 0 )
f += ARROW_SIZE * fMoves[iCol];
return f;
}
float ArrowEffects::GetMoveY(int iCol)
{
const float* fMoves = curr_options->m_fMovesY;
float f = 0;
if( fMoves[iCol] != 0 )
f += ARROW_SIZE * fMoves[iCol];
return f;
}
float ArrowEffects::GetMoveZ(int iCol)
{
const float* fMoves = curr_options->m_fMovesZ;
float f = 0;
if( fMoves[iCol] != 0 )
f += ARROW_SIZE * fMoves[iCol];
return f;
}
#define CENTER_LINE_Y 160 // from fYOffset == 0 #define CENTER_LINE_Y 160 // from fYOffset == 0
#define FADE_DIST_Y 40 #define FADE_DIST_Y 40
+7 -3
View File
@@ -29,9 +29,9 @@ public:
static void GetXYZPos(const PlayerState* player_state, int col, float y_offset, float y_reverse_offset, RageVector3& ret, bool with_reverse= true) static void GetXYZPos(const PlayerState* player_state, int col, float y_offset, float y_reverse_offset, RageVector3& ret, bool with_reverse= true)
{ {
ret.x= GetXPos(player_state, col, y_offset); ret.x= GetMoveX(col) + GetXPos(player_state, col, y_offset);
ret.y= GetYPos(col, y_offset, y_reverse_offset, with_reverse); ret.y= GetMoveY(col) + GetYPos(col, y_offset, y_reverse_offset, with_reverse);
ret.z= GetZPos(col, y_offset); ret.z= GetMoveZ(col) + GetZPos(col, y_offset);
} }
/** /**
@@ -63,6 +63,10 @@ public:
static float ReceptorGetRotationX( const PlayerState* pPlayerState); static float ReceptorGetRotationX( const PlayerState* pPlayerState);
static float ReceptorGetRotationY( const PlayerState* pPlayerState); static float ReceptorGetRotationY( const PlayerState* pPlayerState);
static float GetMoveX(int iCol);
static float GetMoveY(int iCol);
static float GetMoveZ(int iCol);
// fXPos is a horizontal position in pixels relative to the center of the field. // fXPos is a horizontal position in pixels relative to the center of the field.
// This depends on the column of the arrow and possibly the Arrow effect and // This depends on the column of the arrow and possibly the Arrow effect and
// fYPos (in the case of EFFECT_DRUNK). // fYPos (in the case of EFFECT_DRUNK).
+2 -2
View File
@@ -884,10 +884,10 @@ void NoteDisplay::DrawHoldPart(vector<Sprite*> &vpSpr,
switch(column_args.pos_handler->m_spline_mode) switch(column_args.pos_handler->m_spline_mode)
{ {
case NCSM_Disabled: case NCSM_Disabled:
ae_pos.y= fY; ae_pos.y= fY + ArrowEffects::GetMoveY(column_args.column);
break; break;
case NCSM_Offset: case NCSM_Offset:
ae_pos.y= fY; ae_pos.y= fY + ArrowEffects::GetMoveY(column_args.column);
column_args.pos_handler->EvalDerivForBeat(column_args.song_beat, cur_beat, sp_pos_forward); column_args.pos_handler->EvalDerivForBeat(column_args.song_beat, cur_beat, sp_pos_forward);
RageVec3Normalize(&sp_pos_forward, &sp_pos_forward); RageVec3Normalize(&sp_pos_forward, &sp_pos_forward);
break; break;
+63
View File
@@ -76,6 +76,10 @@ void PlayerOptions::Init()
ZERO( m_bTransforms ); ZERO( m_bTransforms );
m_bMuteOnError = false; m_bMuteOnError = false;
m_sNoteSkin = ""; m_sNoteSkin = "";
ZERO( m_fMovesX ); ONE( m_SpeedfMovesX );
ZERO( m_fMovesY ); ONE( m_SpeedfMovesY );
ZERO( m_fMovesZ ); ONE( m_SpeedfMovesZ );
} }
void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds ) void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds )
@@ -110,6 +114,12 @@ void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds )
APPROACH( fSkew ); APPROACH( fSkew );
APPROACH( fPassmark ); APPROACH( fPassmark );
APPROACH( fRandomSpeed ); APPROACH( fRandomSpeed );
for( int i=0; i<16; i++)
APPROACH( fMovesX[i] );
for( int i=0; i<16; i++)
APPROACH( fMovesY[i] );
for( int i=0; i<16; i++)
APPROACH( fMovesZ[i] );
DO_COPY( m_bSetScrollSpeed ); DO_COPY( m_bSetScrollSpeed );
for( int i=0; i<NUM_TURNS; i++ ) for( int i=0; i<NUM_TURNS; i++ )
@@ -227,6 +237,17 @@ void PlayerOptions::GetMods( vector<RString> &AddTo, bool bForceNoteSkin ) const
AddPart( AddTo, m_fEffects[EFFECT_TWIRL], "Twirl" ); AddPart( AddTo, m_fEffects[EFFECT_TWIRL], "Twirl" );
AddPart( AddTo, m_fEffects[EFFECT_ROLL], "Roll" ); AddPart( AddTo, m_fEffects[EFFECT_ROLL], "Roll" );
for( int i=0; i<16; i++)
{
RString s = ssprintf( "MoveX%d", i+1 );
AddPart( AddTo, m_fMovesX[i], s );
s = ssprintf( "MoveY%d", i+1 );
AddPart( AddTo, m_fMovesY[i], s );
s = ssprintf( "MoveZ%d", i+1 );
AddPart( AddTo, m_fMovesZ[i], s );
}
AddPart( AddTo, m_fAppearances[APPEARANCE_HIDDEN], "Hidden" ); AddPart( AddTo, m_fAppearances[APPEARANCE_HIDDEN], "Hidden" );
AddPart( AddTo, m_fAppearances[APPEARANCE_HIDDEN_OFFSET], "HiddenOffset" ); AddPart( AddTo, m_fAppearances[APPEARANCE_HIDDEN_OFFSET], "HiddenOffset" );
AddPart( AddTo, m_fAppearances[APPEARANCE_SUDDEN], "Sudden" ); AddPart( AddTo, m_fAppearances[APPEARANCE_SUDDEN], "Sudden" );
@@ -565,6 +586,20 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
} }
else if( sBit == "muteonerror" ) m_bMuteOnError = on; else if( sBit == "muteonerror" ) m_bMuteOnError = on;
else if( sBit == "random" ) ChooseRandomModifiers(); else if( sBit == "random" ) ChooseRandomModifiers();
else if( sBit.find("move") != sBit.npos)
{
for (int i=0; i<16; i++)
{
RString s = ssprintf( "movex%d", i+1 );
if( sBit == s) SET_FLOAT( fMovesX[i] )
s = ssprintf( "movey%d", i+1 );
if( sBit == s) SET_FLOAT( fMovesY[i] )
s = ssprintf( "movez%d", i+1 );
if( sBit == s) SET_FLOAT( fMovesZ[i] )
}
}
// deprecated mods/left in for compatibility // deprecated mods/left in for compatibility
else if( sBit == "converge" ) SET_FLOAT( fScrolls[SCROLL_CENTERED] ) else if( sBit == "converge" ) SET_FLOAT( fScrolls[SCROLL_CENTERED] )
// end of the list // end of the list
@@ -811,6 +846,12 @@ bool PlayerOptions::operator==( const PlayerOptions &other ) const
COMPARE(m_bTurns[i]); COMPARE(m_bTurns[i]);
for( int i = 0; i < PlayerOptions::NUM_TRANSFORMS; ++i ) for( int i = 0; i < PlayerOptions::NUM_TRANSFORMS; ++i )
COMPARE(m_bTransforms[i]); COMPARE(m_bTransforms[i]);
for( int i = 0; i < 16; ++i )
COMPARE(m_fMovesX[i]);
for( int i = 0; i < 16; ++i )
COMPARE(m_fMovesY[i]);
for( int i = 0; i < 16; ++i )
COMPARE(m_fMovesZ[i]);
#undef COMPARE #undef COMPARE
return true; return true;
} }
@@ -869,6 +910,18 @@ PlayerOptions& PlayerOptions::operator=(PlayerOptions const& other)
{ {
CPY(m_bTransforms[i]); CPY(m_bTransforms[i]);
} }
for( int i = 0; i < 16; ++i )
{
CPY(m_fMovesX[i]);
}
for( int i = 0; i < 16; ++i )
{
CPY(m_fMovesY[i]);
}
for( int i = 0; i < 16; ++i )
{
CPY(m_fMovesZ[i]);
}
#undef CPY #undef CPY
#undef CPY_SPEED #undef CPY_SPEED
return *this; return *this;
@@ -1144,6 +1197,11 @@ public:
FLOAT_INTERFACE(Tilt, PerspectiveTilt, true); FLOAT_INTERFACE(Tilt, PerspectiveTilt, true);
FLOAT_INTERFACE(Passmark, Passmark, true); // Passmark is not sanity checked to the [0, 1] range because LifeMeterBar::IsFailing is the only thing that uses it, and it's used in a <= test. Any theme passing a value outside the [0, 1] range probably expects the result they get. -Kyz FLOAT_INTERFACE(Passmark, Passmark, true); // Passmark is not sanity checked to the [0, 1] range because LifeMeterBar::IsFailing is the only thing that uses it, and it's used in a <= test. Any theme passing a value outside the [0, 1] range probably expects the result they get. -Kyz
FLOAT_INTERFACE(RandomSpeed, RandomSpeed, true); FLOAT_INTERFACE(RandomSpeed, RandomSpeed, true);
MULTICOL_FLOAT_INTERFACE(MoveX, MovesX, true);
MULTICOL_FLOAT_INTERFACE(MoveY, MovesY, true);
MULTICOL_FLOAT_INTERFACE(MoveZ, MovesZ, true);
BOOL_INTERFACE(TurnNone, Turns[PlayerOptions::TURN_NONE]); BOOL_INTERFACE(TurnNone, Turns[PlayerOptions::TURN_NONE]);
BOOL_INTERFACE(Mirror, Turns[PlayerOptions::TURN_MIRROR]); BOOL_INTERFACE(Mirror, Turns[PlayerOptions::TURN_MIRROR]);
BOOL_INTERFACE(Backwards, Turns[PlayerOptions::TURN_BACKWARDS]); BOOL_INTERFACE(Backwards, Turns[PlayerOptions::TURN_BACKWARDS]);
@@ -1568,6 +1626,11 @@ public:
ADD_METHOD(NoStretch); ADD_METHOD(NoStretch);
ADD_METHOD(MuteOnError); ADD_METHOD(MuteOnError);
ADD_MULTICOL_METHOD(MoveX);
ADD_MULTICOL_METHOD(MoveY);
ADD_MULTICOL_METHOD(MoveZ);
ADD_METHOD(NoteSkin); ADD_METHOD(NoteSkin);
ADD_METHOD(FailSetting); ADD_METHOD(FailSetting);
ADD_METHOD(MinTNSToHideNotes); ADD_METHOD(MinTNSToHideNotes);
+42
View File
@@ -71,6 +71,9 @@ public:
ZERO( m_fAppearances ); ONE( m_SpeedfAppearances ); ZERO( m_fAppearances ); ONE( m_SpeedfAppearances );
ZERO( m_fScrolls ); ONE( m_SpeedfScrolls ); ZERO( m_fScrolls ); ONE( m_SpeedfScrolls );
ZERO( m_bTurns ); ZERO( m_bTransforms ); ZERO( m_bTurns ); ZERO( m_bTransforms );
ZERO( m_fMovesX ); ONE( m_SpeedfMovesX );
ZERO( m_fMovesY ); ONE( m_SpeedfMovesY );
ZERO( m_fMovesZ ); ONE( m_SpeedfMovesZ );
}; };
void Init(); void Init();
void Approach( const PlayerOptions& other, float fDeltaSeconds ); void Approach( const PlayerOptions& other, float fDeltaSeconds );
@@ -219,6 +222,10 @@ public:
float m_fPassmark, m_SpeedfPassmark; float m_fPassmark, m_SpeedfPassmark;
float m_fRandomSpeed, m_SpeedfRandomSpeed; float m_fRandomSpeed, m_SpeedfRandomSpeed;
/* The maximum column number is 16.*/
float m_fMovesX[16], m_SpeedfMovesX[16];
float m_fMovesY[16], m_SpeedfMovesY[16];
float m_fMovesZ[16], m_SpeedfMovesZ[16];
bool m_bTurns[NUM_TURNS]; bool m_bTurns[NUM_TURNS];
bool m_bTransforms[NUM_TRANSFORMS]; bool m_bTransforms[NUM_TRANSFORMS];
@@ -257,6 +264,41 @@ public:
bool IsEasierForCourseAndTrail( Course* pCourse, Trail* pTrail ) const; bool IsEasierForCourseAndTrail( Course* pCourse, Trail* pTrail ) const;
}; };
#define ADD_MULTICOL_METHOD( method_name) \
ADD_METHOD( method_name##1 ); \
ADD_METHOD( method_name##2 ); \
ADD_METHOD( method_name##3 ); \
ADD_METHOD( method_name##4 ); \
ADD_METHOD( method_name##5 ); \
ADD_METHOD( method_name##6 ); \
ADD_METHOD( method_name##7 ); \
ADD_METHOD( method_name##8 ); \
ADD_METHOD( method_name##9 ); \
ADD_METHOD( method_name##10 ); \
ADD_METHOD( method_name##11 ); \
ADD_METHOD( method_name##12 ); \
ADD_METHOD( method_name##13 ); \
ADD_METHOD( method_name##14 ); \
ADD_METHOD( method_name##15 ); \
ADD_METHOD( method_name##16 );
#define MULTICOL_FLOAT_INTERFACE(func_name, member, valid) \
FLOAT_INTERFACE(func_name##1, member[0], valid); \
FLOAT_INTERFACE(func_name##2, member[1], valid); \
FLOAT_INTERFACE(func_name##3, member[2], valid); \
FLOAT_INTERFACE(func_name##4, member[3], valid); \
FLOAT_INTERFACE(func_name##5, member[4], valid); \
FLOAT_INTERFACE(func_name##6, member[5], valid); \
FLOAT_INTERFACE(func_name##7, member[6], valid); \
FLOAT_INTERFACE(func_name##8, member[7], valid); \
FLOAT_INTERFACE(func_name##9, member[8], valid); \
FLOAT_INTERFACE(func_name##10, member[9], valid); \
FLOAT_INTERFACE(func_name##11, member[10], valid); \
FLOAT_INTERFACE(func_name##12, member[11], valid); \
FLOAT_INTERFACE(func_name##13, member[12], valid); \
FLOAT_INTERFACE(func_name##14, member[13], valid); \
FLOAT_INTERFACE(func_name##15, member[14], valid); \
FLOAT_INTERFACE(func_name##16, member[15], valid);
#endif #endif
/* /*