From c50b12b8c6f46305745b98d3a2a4bc8f9793becd Mon Sep 17 00:00:00 2001 From: Kyzentun Date: Fri, 17 Apr 2015 16:26:39 -0600 Subject: [PATCH 1/3] Changed toasty logic to trigger multiple times without requiring a W3. --- src/ScoreKeeperNormal.cpp | 33 +++++++++++++++++++-------------- src/ScreenGameplay.cpp | 7 ++++--- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 81f815bcc5..d2cf1b60e3 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -515,8 +515,9 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow ) { case TNS_W1: case TNS_W2: - m_iCurToastyCombo += iNumTapsInRow; - + // TODO: Come up with a design for the theme to list a set of milestone + // values? Current behavior is to just happen at multiples of + // m_ToastyTrigger. -Kyz /* // compile the list of toasty triggers { @@ -536,21 +537,25 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow ) m_iNextToastyAt = -1; } */ - - if( m_iCurToastyCombo >= m_ToastyTrigger && - m_iCurToastyCombo - iNumTapsInRow < m_ToastyTrigger && - !GAMESTATE->m_bDemonstrationOrJukebox ) { - SCREENMAN->PostMessageToTopScreen( SM_PlayToasty, 0 ); - Message msg("ToastyAchieved"); - msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber ); - msg.SetParam( "ToastyCombo", m_iCurToastyCombo ); - MESSAGEMAN->Broadcast(msg); + int old_toastiness= m_iCurToastyCombo / m_ToastyTrigger; + m_iCurToastyCombo += iNumTapsInRow; + int new_toastiness= m_iCurToastyCombo / m_ToastyTrigger; + if(new_toastiness > old_toastiness && + !GAMESTATE->m_bDemonstrationOrJukebox) + { + SCREENMAN->PostMessageToTopScreen( SM_PlayToasty, 0 ); + Message msg("ToastyAchieved"); + msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber ); + msg.SetParam( "ToastyCombo", m_iCurToastyCombo ); + msg.SetParam( "Level", new_toastiness ); + MESSAGEMAN->Broadcast(msg); - // TODO: keep a pointer to the Profile. Don't index with m_PlayerNumber - PROFILEMAN->IncrementToastiesCount( m_pPlayerState->m_PlayerNumber ); + // TODO: keep a pointer to the Profile. Don't index with m_PlayerNumber + PROFILEMAN->IncrementToastiesCount( m_pPlayerState->m_PlayerNumber ); - //m_iCurToastyTrigger++; + //m_iCurToastyTrigger++; + } } break; default: diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index 7b307f3055..1035ec5f91 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -2874,10 +2874,11 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) } else if( SM == SM_PlayToasty ) { - // todo: make multiple toasties work -aj if( g_bEasterEggs ) - if( !m_Toasty.IsTransitioning() && !m_Toasty.IsFinished() ) // don't play if we've already played it once - m_Toasty.StartTransitioning(); + { + m_Toasty.Reset(); + m_Toasty.StartTransitioning(); + } } else if( ScreenMessageHelpers::ScreenMessageToString(SM).find("0Combo") != string::npos ) { From 862eba8f7de271275ea0ecfe8d39ec026ae8e527 Mon Sep 17 00:00:00 2001 From: Kyzentun Date: Fri, 17 Apr 2015 23:24:49 -0600 Subject: [PATCH 2/3] Changed logic to allog ToastyTriggersAt to be a function that returns the next increment. Added ToastyMinTNS metric for controlling the TNS for a toasty. --- Themes/_fallback/metrics.ini | 1 + src/ScoreKeeperNormal.cpp | 151 +++++++++++++++++++++-------------- src/ScoreKeeperNormal.h | 11 +-- 3 files changed, 99 insertions(+), 64 deletions(-) diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index f07e1cb122..f77f37ff9e 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -571,6 +571,7 @@ AvoidMineIncrementsCombo=false UseInternalScoring=true # When you hit it, you know. ToastyTriggersAt=250 +ToastyMinTNS='TapNoteScore_W2' [GameState] # Default song and sort. these don't really matter diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index d2cf1b60e3..7713e9e7f0 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -51,12 +51,10 @@ void ScoreKeeperNormal::Load( m_AvoidMineIncrementsCombo.Load( "Gameplay", "AvoidMineIncrementsCombo" ); m_UseInternalScoring.Load( "Gameplay", "UseInternalScoring" ); - // Toasty triggers (idea from 3.9+) - // Multiple toasty support doesn't seem to be working right now. - // Since it's causing more problems than solutions, I'm going back to - // the old way of a single toasty trigger for now. - //m_vToastyTriggers.Load( "Gameplay", "ToastyTriggersAt" ); - m_ToastyTrigger.Load( "Gameplay", "ToastyTriggersAt" ); + // This can be a function or a number, the type is checked when needed. + // -Kyz + m_toasty_trigger.Load("Gameplay", "ToastyTriggersAt"); + m_toasty_min_tns.Load("Gameplay", "ToastyMinTNS"); // Fill in STATSMAN->m_CurStageStats, calculate multiplier int iTotalPossibleDancePoints = 0; @@ -103,9 +101,12 @@ void ScoreKeeperNormal::Load( m_pPlayerStageStats->m_iPossibleGradePoints = iTotalPossibleGradePoints; m_iScoreRemainder = 0; - m_iCurToastyCombo = 0; - //m_iCurToastyTrigger = 0; - //m_iNextToastyAt = 0; + m_cur_toasty_combo = 0; + m_cur_toasty_level= 0; + // Initialize m_next_toasty_at to 0 so that CalcNextToastyAt just needs to + // add the value. -Kyz + m_next_toasty_at= 0; + m_next_toasty_at= CalcNextToastyAt(m_cur_toasty_level); m_iMaxScoreSoFar = 0; m_iPointBonus = 0; m_iNumTapsAndHolds = 0; @@ -329,6 +330,62 @@ void ScoreKeeperNormal::AddScoreInternal( TapNoteScore score ) } } +int ScoreKeeperNormal::CalcNextToastyAt(int level) +{ + Lua* L= LUA->Get(); + m_toasty_trigger.PushSelf(L); + const int default_amount= 250; + int amount= default_amount; + bool erred= false; + switch(lua_type(L, 1)) + { + case LUA_TNUMBER: + amount= lua_tointeger(L, 1); + break; + case LUA_TFUNCTION: + { + RString err= "Error running ToastyTriggersAt: "; + LuaHelpers::Push(L, m_pPlayerState->m_PlayerNumber); + lua_pushnumber(L, level); + if(LuaHelpers::RunScriptOnStack(L, err, 2, 1, true)) + { + if(lua_isnumber(L, -1)) + { + amount= lua_tointeger(L, -1); + } + else + { + LuaHelpers::ReportScriptError("Gameplay::ToastyTriggersAt " + "function must return a number greater than 0."); + erred= true; + } + } + else + { + erred= true; + } + } + break; + default: + LuaHelpers::ReportScriptError("Gameplay::ToastyTriggersAt metric has " + "a nonsensical type, it must be a number or a function."); + erred= true; + break; + } + if(amount <= 0) + { + if(!erred) + { + LuaHelpers::ReportScriptError("The ToastyTriggersAt value cannot be " + "less than or equal to 0 because that would be silly."); + } + amount= default_amount; + } + lua_settop(L, 0); + LUA->Release(L); + return m_next_toasty_at + amount; +} + void ScoreKeeperNormal::HandleTapScore( const TapNote &tn ) { TapNoteScore tns = tn.result.tns; @@ -504,66 +561,42 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow ) if( (GamePreferences::m_AutoPlay != PC_HUMAN || m_pPlayerState->m_PlayerOptions.GetCurrent().m_fPlayerAutoPlay != 0) && !GAMESTATE->m_bDemonstrationOrJukebox ) // cheaters always prosper >:D -aj comment edit { - m_iCurToastyCombo = 0; + m_cur_toasty_combo = 0; return; } #endif //DEBUG // Toasty combo - //vector iToastyMilestones; - switch( scoreOfLastTap ) + if(scoreOfLastTap >= m_toasty_min_tns) { - case TNS_W1: - case TNS_W2: - // TODO: Come up with a design for the theme to list a set of milestone - // values? Current behavior is to just happen at multiples of - // m_ToastyTrigger. -Kyz - /* - // compile the list of toasty triggers + m_cur_toasty_combo += iNumTapsInRow; + if(m_cur_toasty_combo > m_next_toasty_at && + !GAMESTATE->m_bDemonstrationOrJukebox) { - Lua *L = LUA->Get(); - m_vToastyTriggers.PushSelf(L); - LuaHelpers::ReadArrayFromTable(iToastyMilestones, L); - lua_pop( L, 1 ); - LUA->Release(L); + ++m_cur_toasty_level; + // Broadcast the message before posting the screen message so that the + // transition layer can catch the message to know the level and respond + // accordingly. -Kyz + Message msg("ToastyAchieved"); + msg.SetParam("PlayerNumber", m_pPlayerState->m_PlayerNumber); + msg.SetParam("ToastyCombo", m_cur_toasty_combo); + msg.SetParam("Level", m_cur_toasty_level); + MESSAGEMAN->Broadcast(msg); + // TODO: keep a pointer to the Profile. Don't index with m_PlayerNumber + SCREENMAN->PostMessageToTopScreen(SM_PlayToasty, 0); + PROFILEMAN->IncrementToastiesCount(m_pPlayerState->m_PlayerNumber); + m_next_toasty_at= CalcNextToastyAt(m_cur_toasty_level); } - // find out which one we're at. - if(m_iCurToastyTrigger <= int(iToastyMilestones.size())) - { - m_iNextToastyAt = iToastyMilestones[m_iCurToastyTrigger]; - } - else // out of index value? then don't make it toasty! - { - m_iNextToastyAt = -1; - } - */ - { - int old_toastiness= m_iCurToastyCombo / m_ToastyTrigger; - m_iCurToastyCombo += iNumTapsInRow; - int new_toastiness= m_iCurToastyCombo / m_ToastyTrigger; - if(new_toastiness > old_toastiness && - !GAMESTATE->m_bDemonstrationOrJukebox) - { - SCREENMAN->PostMessageToTopScreen( SM_PlayToasty, 0 ); - Message msg("ToastyAchieved"); - msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber ); - msg.SetParam( "ToastyCombo", m_iCurToastyCombo ); - msg.SetParam( "Level", new_toastiness ); - MESSAGEMAN->Broadcast(msg); - - // TODO: keep a pointer to the Profile. Don't index with m_PlayerNumber - PROFILEMAN->IncrementToastiesCount( m_pPlayerState->m_PlayerNumber ); - - //m_iCurToastyTrigger++; - } - } - break; - default: - m_iCurToastyCombo = 0; + } + else + { + m_cur_toasty_combo = 0; + m_cur_toasty_level= 0; + m_next_toasty_at= 0; + m_next_toasty_at= CalcNextToastyAt(m_cur_toasty_level); Message msg("ToastyDropped"); msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber ); MESSAGEMAN->Broadcast(msg); - break; } // TODO: Remove indexing with PlayerNumber @@ -575,7 +608,7 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow ) Message msg( "ScoreChanged" ); msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber ); msg.SetParam( "MultiPlayer", m_pPlayerState->m_mp ); - msg.SetParam( "ToastyCombo", m_iCurToastyCombo ); + msg.SetParam( "ToastyCombo", m_cur_toasty_combo ); MESSAGEMAN->Broadcast( msg ); } diff --git a/src/ScoreKeeperNormal.h b/src/ScoreKeeperNormal.h index 89e444f392..c648765b21 100644 --- a/src/ScoreKeeperNormal.h +++ b/src/ScoreKeeperNormal.h @@ -18,6 +18,7 @@ AutoScreenMessage( SM_PlayToasty ); class ScoreKeeperNormal: public ScoreKeeper { void AddScoreInternal( TapNoteScore score ); + int CalcNextToastyAt(int level); int m_iScoreRemainder; int m_iMaxPossiblePoints; @@ -26,9 +27,9 @@ class ScoreKeeperNormal: public ScoreKeeper int m_iNumTapsAndHolds; int m_iMaxScoreSoFar; // for nonstop scoring int m_iPointBonus; // the difference to award at the end - int m_iCurToastyCombo; - //int m_iCurToastyTrigger; - //int m_iNextToastyAt; + int m_cur_toasty_combo; + int m_cur_toasty_level; + int m_next_toasty_at; bool m_bIsLastSongInCourse; bool m_bIsBeginner; @@ -43,8 +44,8 @@ class ScoreKeeperNormal: public ScoreKeeper ThemeMetric m_AvoidMineIncrementsCombo; ThemeMetric m_UseInternalScoring; - //ThemeMetric m_vToastyTriggers; - ThemeMetric m_ToastyTrigger; + ThemeMetric m_toasty_min_tns; + ThemeMetric m_toasty_trigger; vector m_apSteps; From 9314555e6dc9f4f4ab996e7c7d2cb71846949a9c Mon Sep 17 00:00:00 2001 From: Kyzentun Date: Sat, 18 Apr 2015 08:52:57 -0600 Subject: [PATCH 3/3] Added preference for showing multiple toasties in one song. Added IsWaiting to Transition. --- Themes/_fallback/Languages/en.ini | 2 ++ Themes/_fallback/metrics.ini | 3 ++- src/PrefsManager.cpp | 1 + src/PrefsManager.h | 1 + src/ScoreKeeperNormal.cpp | 3 ++- src/ScreenGameplay.cpp | 10 +++++++--- src/ScreenOptionsMasterPrefs.cpp | 1 + src/Transition.h | 1 + 8 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 091d55a73c..f06cafabd8 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -345,6 +345,7 @@ AllowExtraStage=When enabled (and Event Mode isn't on), allows the player to ear AllowSongDeletion=Allow players to permanently delete songs from the system by pressing Ctrl+Backspace when browsing the music wheel. AllowW1=Enable or disable fantastic judgement. NEVER - never show Fantastic, COURSES ONLY - only during nonstop/oni modes, ALWAYS - all modes of play. AllowMultipleHighScoreWithSameName=If turned off, only the highest score with a given name will be saved. If turned on, it will allow mutliple high scores with a given name to be saved. +AllowMultipleToasties=Allow multiple toasties to be shown in one song. Announcer=Choose from this list of installed announcer packs. Appearance=Appearance Appearance Options=Change the theme, announcer, and other style options. @@ -943,6 +944,7 @@ AllowExtraStage=Allow Extra Stage AllowSongDeletion=Allow Song Deletion AllowW1=Fantastic Timing AllowMultipleHighScoreWithSameName=Competitive Mode +AllowMultipleToasties=Extra Toast Alter=Alter Announcer=Announcer Appearance=Appearance diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index f77f37ff9e..126610b484 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -3100,7 +3100,7 @@ Fallback="ScreenOptionsServiceChild" NextScreen="ScreenOptionsService" PrevScreen="ScreenOptionsService" # stuff tied to arcade features -LineNames="1,2,3,4,5,6,7,8,9,HHLP,10,11,12,13,14" +LineNames="1,2,3,4,5,6,7,8,AMT,9,HHLP,10,11,12,13,14" Line1="conf,GetRankingName" Line2="conf,CoinMode" Line3="conf,SongsPerPlay" @@ -3109,6 +3109,7 @@ Line5="conf,Premium" Line6="conf,EventMode" Line7="conf,AllowMultipleHighScoreWithSameName" Line8="conf,ComboContinuesBetweenSongs" +LineAMT="conf,AllowMultipleToasties" Line9="conf,Disqualification" LineHHLP="conf,HarshHotLifePenalty" Line10="conf,FailOffForFirstStageEasy" diff --git a/src/PrefsManager.cpp b/src/PrefsManager.cpp index 2bdb98f58a..8d14c32e9d 100644 --- a/src/PrefsManager.cpp +++ b/src/PrefsManager.cpp @@ -223,6 +223,7 @@ PrefsManager::PrefsManager() : m_iSongsPerPlay ( "SongsPerPlay", 3, ValidateSongsPerPlay ), m_bDelayedCreditsReconcile ( "DelayedCreditsReconcile", false ), m_bComboContinuesBetweenSongs ( "ComboContinuesBetweenSongs", false ), + m_AllowMultipleToasties("AllowMultipleToasties", true), m_MinTNSToHideNotes("MinTNSToHideNotes", TNS_W3), m_ShowSongOptions ( "ShowSongOptions", Maybe_NO ), m_bDancePointsForOni ( "DancePointsForOni", true ), diff --git a/src/PrefsManager.h b/src/PrefsManager.h index 4aded80335..f710a1c2dd 100644 --- a/src/PrefsManager.h +++ b/src/PrefsManager.h @@ -215,6 +215,7 @@ public: Preference m_iSongsPerPlay; Preference m_bDelayedCreditsReconcile; // zuh? Preference m_bComboContinuesBetweenSongs; + Preference m_AllowMultipleToasties; Preference m_MinTNSToHideNotes; Preference m_ShowSongOptions; Preference m_bDancePointsForOni; diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 7713e9e7f0..98131d1e1b 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -582,8 +582,9 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow ) msg.SetParam("ToastyCombo", m_cur_toasty_combo); msg.SetParam("Level", m_cur_toasty_level); MESSAGEMAN->Broadcast(msg); - // TODO: keep a pointer to the Profile. Don't index with m_PlayerNumber SCREENMAN->PostMessageToTopScreen(SM_PlayToasty, 0); + // TODO: keep a pointer to the Profile. Don't index with m_PlayerNumber + // TODO: Make the profile count the level and combo of the toasty. -Kyz PROFILEMAN->IncrementToastiesCount(m_pPlayerState->m_PlayerNumber); m_next_toasty_at= CalcNextToastyAt(m_cur_toasty_level); } diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index 1035ec5f91..f5a0065131 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -2874,10 +2874,14 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) } else if( SM == SM_PlayToasty ) { - if( g_bEasterEggs ) + if(g_bEasterEggs) { - m_Toasty.Reset(); - m_Toasty.StartTransitioning(); + if(PREFSMAN->m_AllowMultipleToasties || + m_Toasty.IsWaiting()) + { + m_Toasty.Reset(); + m_Toasty.StartTransitioning(); + } } } else if( ScreenMessageHelpers::ScreenMessageToString(SM).find("0Combo") != string::npos ) diff --git a/src/ScreenOptionsMasterPrefs.cpp b/src/ScreenOptionsMasterPrefs.cpp index cb87d495dd..1d2f1775ad 100644 --- a/src/ScreenOptionsMasterPrefs.cpp +++ b/src/ScreenOptionsMasterPrefs.cpp @@ -785,6 +785,7 @@ static void InitializeConfOptions() ADD( ConfOption( "AllowExtraStage", MovePref, "Off","On" ) ); ADD( ConfOption( "AllowMultipleHighScoreWithSameName", MovePref, "Off", "On" ) ); ADD( ConfOption( "ComboContinuesBetweenSongs", MovePref, "Off", "On") ); + ADD(ConfOption("AllowMultipleToasties", MovePref, "Off", "On")); ADD( ConfOption( "Disqualification", MovePref, "Off","On" ) ); ADD( ConfOption( "HarshHotLifePenalty", MovePref, "Off", "On") ); ADD( ConfOption( "FailOffForFirstStageEasy", MovePref, "Off","On" ) ); diff --git a/src/Transition.h b/src/Transition.h index 460eae535f..b39c2dba9d 100644 --- a/src/Transition.h +++ b/src/Transition.h @@ -22,6 +22,7 @@ public: virtual float GetTweenTimeLeft() const; void Reset(); // explicitly allow transitioning again + bool IsWaiting() const { return m_State == waiting; }; bool IsTransitioning() const { return m_State == transitioning; }; bool IsFinished() const { return m_State == finished; };