diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml index 67e9c68c6c..e833ab7e51 100644 --- a/Docs/Luadoc/Lua.xml +++ b/Docs/Luadoc/Lua.xml @@ -1125,6 +1125,11 @@ + + + + + diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index c203e47a07..04a394ac5a 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -3447,6 +3447,11 @@ save yourself some time, copy this for undocumented things: If the optional second argument is passed, sets the speed at which the transition occurs. + + + + + diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 78cd3e3859..e5170e0576 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -569,24 +569,28 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float return fPixelOffsetFromCenter; } -float ArrowEffects::GetRotationX(float fYOffset) +float ArrowEffects::GetRotationX(const PlayerState* pPlayerState, float fYOffset, bool bIsHoldCap) { const float* fEffects = curr_options->m_fEffects; float fRotation = 0; - if( fEffects[PlayerOptions::EFFECT_ROLL] != 0 ) + if( fEffects[PlayerOptions::EFFECT_CONFUSION_X] != 0 || fEffects[PlayerOptions::EFFECT_CONFUSION_X_OFFSET] != 0 ) + fRotation += ReceptorGetRotationX( pPlayerState ); + if( fEffects[PlayerOptions::EFFECT_ROLL] != 0 && !bIsHoldCap ) { - fRotation = fEffects[PlayerOptions::EFFECT_ROLL] * fYOffset/2; + fRotation += fEffects[PlayerOptions::EFFECT_ROLL] * fYOffset/2; } return fRotation; } -float ArrowEffects::GetRotationY(float fYOffset) +float ArrowEffects::GetRotationY(const PlayerState* pPlayerState, float fYOffset) { const float* fEffects = curr_options->m_fEffects; float fRotation = 0; + if( fEffects[PlayerOptions::EFFECT_CONFUSION_Y] != 0 || fEffects[PlayerOptions::EFFECT_CONFUSION_Y_OFFSET] != 0 ) + fRotation += ReceptorGetRotationY( pPlayerState ); if( fEffects[PlayerOptions::EFFECT_TWIRL] != 0 ) { - fRotation = fEffects[PlayerOptions::EFFECT_TWIRL] * fYOffset/2; + fRotation += fEffects[PlayerOptions::EFFECT_TWIRL] * fYOffset/2; } return fRotation; } @@ -595,7 +599,7 @@ float ArrowEffects::GetRotationZ( const PlayerState* pPlayerState, float fNoteBe { const float* fEffects = curr_options->m_fEffects; float fRotation = 0; - if( fEffects[PlayerOptions::EFFECT_CONFUSION] != 0 ) + if( fEffects[PlayerOptions::EFFECT_CONFUSION] != 0 || fEffects[PlayerOptions::EFFECT_CONFUSION_OFFSET] != 0 ) fRotation += ReceptorGetRotationZ( pPlayerState ); // As usual, enable dizzy hold heads at your own risk. -Wolfman2000 @@ -616,6 +620,9 @@ float ArrowEffects::ReceptorGetRotationZ( const PlayerState* pPlayerState ) const float* fEffects = curr_options->m_fEffects; float fRotation = 0; + if( fEffects[PlayerOptions::EFFECT_CONFUSION_OFFSET] != 0 ) + fRotation += fEffects[PlayerOptions::EFFECT_CONFUSION_OFFSET] * 180.0f/PI; + if( fEffects[PlayerOptions::EFFECT_CONFUSION] != 0 ) { float fConfRotation = pPlayerState->m_Position.m_fSongBeatVisible; @@ -624,6 +631,47 @@ float ArrowEffects::ReceptorGetRotationZ( const PlayerState* pPlayerState ) fConfRotation *= -180/PI; fRotation += fConfRotation; } + + return fRotation; +} + +float ArrowEffects::ReceptorGetRotationX( const PlayerState* pPlayerState ) +{ + const float* fEffects = curr_options->m_fEffects; + float fRotation = 0; + + if( fEffects[PlayerOptions::EFFECT_CONFUSION_X_OFFSET] != 0 ) + fRotation += fEffects[PlayerOptions::EFFECT_CONFUSION_X_OFFSET] * 180.0f/PI; + + if( fEffects[PlayerOptions::EFFECT_CONFUSION_X] != 0 ) + { + float fConfRotation = pPlayerState->m_Position.m_fSongBeatVisible; + fConfRotation *= fEffects[PlayerOptions::EFFECT_CONFUSION_X]; + fConfRotation = fmodf( fConfRotation, 2*PI ); + fConfRotation *= -180/PI; + fRotation += fConfRotation; + } + + return fRotation; +} + +float ArrowEffects::ReceptorGetRotationY( const PlayerState* pPlayerState ) +{ + const float* fEffects = curr_options->m_fEffects; + float fRotation = 0; + + if( fEffects[PlayerOptions::EFFECT_CONFUSION_Y_OFFSET] != 0 ) + fRotation += fEffects[PlayerOptions::EFFECT_CONFUSION_Y_OFFSET] * 180.0f/PI; + + if( fEffects[PlayerOptions::EFFECT_CONFUSION_Y] != 0 ) + { + float fConfRotation = pPlayerState->m_Position.m_fSongBeatVisible; + fConfRotation *= fEffects[PlayerOptions::EFFECT_CONFUSION_Y]; + fConfRotation = fmodf( fConfRotation, 2*PI ); + fConfRotation *= -180/PI; + fRotation += fConfRotation; + } + return fRotation; } @@ -933,7 +981,8 @@ namespace { PlayerState *ps = Luna::check( L, 1 ); ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent()); - lua_pushnumber(L, ArrowEffects::GetRotationX(FArg(2))); + bool bIsHoldCap = false; + lua_pushnumber(L, ArrowEffects::GetRotationX(ps,FArg(2), bIsHoldCap)); return 1; } @@ -942,7 +991,7 @@ namespace { PlayerState *ps = Luna::check( L, 1 ); ArrowEffects::SetCurrentOptions(&ps->m_PlayerOptions.GetCurrent()); - lua_pushnumber(L, ArrowEffects::GetRotationY(FArg(2))); + lua_pushnumber(L, ArrowEffects::GetRotationY(ps,FArg(2))); return 1; } diff --git a/src/ArrowEffects.h b/src/ArrowEffects.h index 811f2d11fe..9568f19846 100644 --- a/src/ArrowEffects.h +++ b/src/ArrowEffects.h @@ -57,8 +57,11 @@ public: // Due to the handling logic for holds on Twirl, we need to use an offset instead. // It's more intuitive for Roll to be based off offset, so use an offset there too. - static float GetRotationX(float fYOffset); - static float GetRotationY(float fYOffset); + static float GetRotationX(const PlayerState* pPlayerState, float fYOffset, bool bIsHoldCap); + static float GetRotationY(const PlayerState* pPlayerState, float fYOffset); + + static float ReceptorGetRotationX( const PlayerState* pPlayerState); + static float ReceptorGetRotationY( const PlayerState* pPlayerState); // 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 diff --git a/src/NoteDisplay.cpp b/src/NoteDisplay.cpp index ddfde55e93..7f97a7484d 100644 --- a/src/NoteDisplay.cpp +++ b/src/NoteDisplay.cpp @@ -937,10 +937,10 @@ void NoteDisplay::DrawHoldPart(vector &vpSpr, { case NCSM_Disabled: // XXX: Actor rotations use degrees, Math uses radians. Convert here. - ae_rot.y= ArrowEffects::GetRotationY(fYOffset) * PI_180; + ae_rot.y= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset) * PI_180; break; case NCSM_Offset: - ae_rot.y= ArrowEffects::GetRotationY(fYOffset) * PI_180; + ae_rot.y= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset) * PI_180; column_args.rot_handler->EvalForBeat(column_args.song_beat, cur_beat, sp_rot); break; case NCSM_Position: @@ -1291,19 +1291,13 @@ void NoteDisplay::DrawActor(const TapNote& tn, Actor* pActor, NotePart part, switch(column_args.rot_handler->m_spline_mode) { case NCSM_Disabled: - if(!bIsHoldCap) - { - ae_rot.x= ArrowEffects::GetRotationX(fYOffset); - } - ae_rot.y= ArrowEffects::GetRotationY(fYOffset); + ae_rot.x= ArrowEffects::GetRotationX(m_pPlayerState, fYOffset, bIsHoldCap); + ae_rot.y= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset); ae_rot.z= ArrowEffects::GetRotationZ(m_pPlayerState, fBeat, bIsHoldHead); break; case NCSM_Offset: - if(!bIsHoldCap) - { - ae_rot.x= ArrowEffects::GetRotationX(fYOffset); - } - ae_rot.y= ArrowEffects::GetRotationY(fYOffset); + ae_rot.x= ArrowEffects::GetRotationX(m_pPlayerState, fYOffset, bIsHoldCap); + ae_rot.y= ArrowEffects::GetRotationY(m_pPlayerState, fYOffset); ae_rot.z= ArrowEffects::GetRotationZ(m_pPlayerState, fBeat, bIsHoldHead); column_args.rot_handler->EvalForBeat(column_args.song_beat, spline_beat, sp_rot); break; @@ -1466,9 +1460,13 @@ void NoteColumnRenderer::UpdateReceptorGhostStuff(Actor* receptor) const { case NCSM_Disabled: ae_rot.z= ArrowEffects::ReceptorGetRotationZ(player_state); + ae_rot.x= ArrowEffects::ReceptorGetRotationX(player_state); + ae_rot.y= ArrowEffects::ReceptorGetRotationY(player_state); break; case NCSM_Offset: ae_rot.z= ArrowEffects::ReceptorGetRotationZ(player_state); + ae_rot.x= ArrowEffects::ReceptorGetRotationX(player_state); + ae_rot.y= ArrowEffects::ReceptorGetRotationY(player_state); NCR_current.m_rot_handler.EvalForReceptor(song_beat, sp_rot); break; case NCSM_Position: diff --git a/src/PlayerOptions.cpp b/src/PlayerOptions.cpp index 1195b3fb06..35bc19e8f6 100644 --- a/src/PlayerOptions.cpp +++ b/src/PlayerOptions.cpp @@ -210,6 +210,11 @@ void PlayerOptions::GetMods( vector &AddTo, bool bForceNoteSkin ) const AddPart( AddTo, m_fEffects[EFFECT_DRUNK], "Drunk" ); AddPart( AddTo, m_fEffects[EFFECT_DIZZY], "Dizzy" ); AddPart( AddTo, m_fEffects[EFFECT_CONFUSION], "Confusion" ); + AddPart( AddTo, m_fEffects[EFFECT_CONFUSION_OFFSET], "ConfusionOffset" ); + AddPart( AddTo, m_fEffects[EFFECT_CONFUSION_X], "ConfusionX" ); + AddPart( AddTo, m_fEffects[EFFECT_CONFUSION_X_OFFSET], "ConfusionXOffset" ); + AddPart( AddTo, m_fEffects[EFFECT_CONFUSION_Y], "ConfusionY" ); + AddPart( AddTo, m_fEffects[EFFECT_CONFUSION_Y_OFFSET], "ConfusionYOffset" ); AddPart( AddTo, m_fEffects[EFFECT_MINI], "Mini" ); AddPart( AddTo, m_fEffects[EFFECT_TINY], "Tiny" ); AddPart( AddTo, m_fEffects[EFFECT_FLIP], "Flip" ); @@ -464,6 +469,11 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut else if( sBit == "drunk" ) SET_FLOAT( fEffects[EFFECT_DRUNK] ) else if( sBit == "dizzy" ) SET_FLOAT( fEffects[EFFECT_DIZZY] ) else if( sBit == "confusion" ) SET_FLOAT( fEffects[EFFECT_CONFUSION] ) + else if( sBit == "confusionoffset" ) SET_FLOAT( fEffects[EFFECT_CONFUSION_OFFSET] ) + else if( sBit == "confusionx" ) SET_FLOAT( fEffects[EFFECT_CONFUSION_X] ) + else if( sBit == "confusionxoffset" ) SET_FLOAT( fEffects[EFFECT_CONFUSION_X_OFFSET] ) + else if( sBit == "confusiony" ) SET_FLOAT( fEffects[EFFECT_CONFUSION_Y] ) + else if( sBit == "confusionyoffset" ) SET_FLOAT( fEffects[EFFECT_CONFUSION_Y_OFFSET] ) else if( sBit == "mini" ) SET_FLOAT( fEffects[EFFECT_MINI] ) else if( sBit == "tiny" ) SET_FLOAT( fEffects[EFFECT_TINY] ) else if( sBit == "flip" ) SET_FLOAT( fEffects[EFFECT_FLIP] ) @@ -1096,6 +1106,11 @@ public: FLOAT_INTERFACE(Drunk, Effects[PlayerOptions::EFFECT_DRUNK], true); FLOAT_INTERFACE(Dizzy, Effects[PlayerOptions::EFFECT_DIZZY], true); FLOAT_INTERFACE(Confusion, Effects[PlayerOptions::EFFECT_CONFUSION], true); + FLOAT_INTERFACE(ConfusionOffset, Effects[PlayerOptions::EFFECT_CONFUSION_OFFSET], true); + FLOAT_INTERFACE(ConfusionX, Effects[PlayerOptions::EFFECT_CONFUSION_X], true); + FLOAT_INTERFACE(ConfusionXOffset, Effects[PlayerOptions::EFFECT_CONFUSION_X_OFFSET], true); + FLOAT_INTERFACE(ConfusionY, Effects[PlayerOptions::EFFECT_CONFUSION_Y], true); + FLOAT_INTERFACE(ConfusionYOffset, Effects[PlayerOptions::EFFECT_CONFUSION_Y_OFFSET], true); FLOAT_INTERFACE(Mini, Effects[PlayerOptions::EFFECT_MINI], true); FLOAT_INTERFACE(Tiny, Effects[PlayerOptions::EFFECT_TINY], true); FLOAT_INTERFACE(Flip, Effects[PlayerOptions::EFFECT_FLIP], true); @@ -1482,6 +1497,11 @@ public: ADD_METHOD(Drunk); ADD_METHOD(Dizzy); ADD_METHOD(Confusion); + ADD_METHOD(ConfusionOffset); + ADD_METHOD(ConfusionX); + ADD_METHOD(ConfusionXOffset); + ADD_METHOD(ConfusionY); + ADD_METHOD(ConfusionYOffset); ADD_METHOD(Mini); ADD_METHOD(Tiny); ADD_METHOD(Flip); diff --git a/src/PlayerOptions.h b/src/PlayerOptions.h index e903f8c416..cd5ff88615 100644 --- a/src/PlayerOptions.h +++ b/src/PlayerOptions.h @@ -111,6 +111,11 @@ public: EFFECT_DRUNK, EFFECT_DIZZY, EFFECT_CONFUSION, + EFFECT_CONFUSION_OFFSET, + EFFECT_CONFUSION_X, + EFFECT_CONFUSION_X_OFFSET, + EFFECT_CONFUSION_Y, + EFFECT_CONFUSION_Y_OFFSET, EFFECT_MINI, EFFECT_TINY, EFFECT_FLIP,