From e60ac1395daf1434d4707509719e32f1c152311d Mon Sep 17 00:00:00 2001 From: sigatrev Date: Fri, 5 Sep 2014 22:30:33 -0500 Subject: [PATCH 1/8] expose tap notes for judgment message allow themes access to as much information as possible on judgments --- Docs/Luadoc/Lua.xml | 27 +++++++ Docs/Luadoc/LuaDocumentation.xml | 69 ++++++++++++++++ src/NoteTypes.cpp | 130 ++++++++++++++++++++++++------- src/NoteTypes.h | 37 +++++---- src/Player.cpp | 70 +++++++++++------ src/Player.h | 6 +- 6 files changed, 272 insertions(+), 67 deletions(-) diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml index cca7e62894..9573dfd079 100644 --- a/Docs/Luadoc/Lua.xml +++ b/Docs/Luadoc/Lua.xml @@ -1638,6 +1638,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index 4dbeb7bbc1..8c212b20a0 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -4634,6 +4634,75 @@ save yourself some time, copy this for undocumented things: Returns true if the Style needs to be zoomed out with two players. + + + Returns the of the Tap Note. + + + Returns the of the Tap Note. + + + Returns the of the Tap Note. + + + Returns the of the Tap Note. + + + Returns the of the Tap Note. Relevant for routine steps. + + + Returns the Attack Modifiers of the Tap Note. + + + Returns the Attack Duration of the Tap Note in seconds. + + + Returns the Keysound Index of the Tap Note. + + + Returns the Hold Duration of the Tap Note in beats. + + + Returns the of the Tap Note. + + + + + Returns the of the Tap Note. + + + Returns the TapNotOffset of the Tap Note. + + + Returns true if the Tap Note was judged with a result that would stop it from drawing. + + + + + Returns the of the Hold Note. + + + Returns the life of the Hold Note. + + + Returns the amount of time the hold has overlapped the target. + + + Returns the last beat the Hold Note was held. + + + Returns the number of checkpoints hit. + + + Returns the number of checkpoints missed. + + + Returns true if the note was initiated and is being held. + + + Returns true if the note was initiated. + + Loads the TextBanner from the specified metrics group. diff --git a/src/NoteTypes.cpp b/src/NoteTypes.cpp index b164ab7663..851a981dfe 100644 --- a/src/NoteTypes.cpp +++ b/src/NoteTypes.cpp @@ -5,47 +5,47 @@ #include "XmlFile.h" #include "LocalizedString.h" -TapNote TAP_EMPTY ( TapNoteType_Empty, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); -TapNote TAP_ORIGINAL_TAP ( TapNoteType_Tap, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); -TapNote TAP_ORIGINAL_LIFT ( TapNoteType_Lift, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); -TapNote TAP_ORIGINAL_HOLD_HEAD ( TapNoteType_HoldHead, TapNoteSubType_Hold, TapNoteSource_Original, "", 0, -1 ); -TapNote TAP_ORIGINAL_ROLL_HEAD ( TapNoteType_HoldHead, TapNoteSubType_Roll, TapNoteSource_Original, "", 0, -1 ); -TapNote TAP_ORIGINAL_MINE ( TapNoteType_Mine, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); -TapNote TAP_ORIGINAL_ATTACK ( TapNoteType_Attack, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); -TapNote TAP_ORIGINAL_AUTO_KEYSOUND ( TapNoteType_AutoKeysound,TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); -TapNote TAP_ORIGINAL_FAKE ( TapNoteType_Fake, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); +TapNote TAP_EMPTY ( TapNoteType_Empty, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); +TapNote TAP_ORIGINAL_TAP ( TapNoteType_Tap, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); +TapNote TAP_ORIGINAL_LIFT ( TapNoteType_Lift, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); +TapNote TAP_ORIGINAL_HOLD_HEAD ( TapNoteType_HoldHead, TapNoteSubType_Hold, TapNoteSource_Original, "", 0, -1 ); +TapNote TAP_ORIGINAL_ROLL_HEAD ( TapNoteType_HoldHead, TapNoteSubType_Roll, TapNoteSource_Original, "", 0, -1 ); +TapNote TAP_ORIGINAL_MINE ( TapNoteType_Mine, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); +TapNote TAP_ORIGINAL_ATTACK ( TapNoteType_Attack, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); +TapNote TAP_ORIGINAL_AUTO_KEYSOUND ( TapNoteType_AutoKeysound,TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); +TapNote TAP_ORIGINAL_FAKE ( TapNoteType_Fake, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 ); //TapNote TAP_ORIGINAL_MINE_HEAD ( TapNoteType_HoldHead, TapNoteSubType_Mine, TapNoteSource_Original, "", 0, -1 ); -TapNote TAP_ADDITION_TAP ( TapNoteType_Tap, TapNoteSubType_Invalid, TapNoteSource_Addition, "", 0, -1 ); -TapNote TAP_ADDITION_MINE ( TapNoteType_Mine, TapNoteSubType_Invalid, TapNoteSource_Addition, "", 0, -1 ); +TapNote TAP_ADDITION_TAP ( TapNoteType_Tap, TapNoteSubType_Invalid, TapNoteSource_Addition, "", 0, -1 ); +TapNote TAP_ADDITION_MINE ( TapNoteType_Mine, TapNoteSubType_Invalid, TapNoteSource_Addition, "", 0, -1 ); static const char *TapNoteTypeNames[] = { - "Empty", - "Tap", - "HoldHead", - "HoldTail", - "Mine", - "Lift", - "Attack", - "AutoKeySound", - "Fake", + "Empty", + "Tap", + "HoldHead", + "HoldTail", + "Mine", + "Lift", + "Attack", + "AutoKeySound", + "Fake", }; XToString( TapNoteType ); XToLocalizedString( TapNoteType ); LuaXType( TapNoteType ); static const char *TapNoteSubTypeNames[] = { - "Hold", - "Roll", - //"Mine", + "Hold", + "Roll", + //"Mine", }; XToString( TapNoteSubType ); XToLocalizedString( TapNoteSubType ); LuaXType( TapNoteSubType ); static const char *TapNoteSourceNames[] = { - "Original", - "Addition", + "Original", + "Addition", }; XToString( TapNoteSource ); XToLocalizedString( TapNoteSource ); @@ -127,7 +127,7 @@ static const int ROWS_PER_MEASURE = ROWS_PER_BEAT * BEATS_PER_MEASURE; * @return the quantized NoteType. */ NoteType GetNoteType( int row ) { - if( row % (ROWS_PER_MEASURE/4) == 0) return NOTE_TYPE_4TH; + if( row % (ROWS_PER_MEASURE/4) == 0) return NOTE_TYPE_4TH; else if( row % (ROWS_PER_MEASURE/8) == 0) return NOTE_TYPE_8TH; else if( row % (ROWS_PER_MEASURE/12) == 0) return NOTE_TYPE_12TH; else if( row % (ROWS_PER_MEASURE/16) == 0) return NOTE_TYPE_16TH; @@ -200,6 +200,84 @@ float HoldNoteResult::GetLastHeldBeat() const return NoteRowToBeat(iLastHeldRow); } +// lua start +#include "LuaBinding.h" + +/** @brief Allow Lua to have access to the TapNoteResult. */ +class LunaTapNoteResult: public Luna +{ +public: + DEFINE_METHOD(GetTapNoteScore, tns); + DEFINE_METHOD(GetTapNoteOffset, fTapNoteOffset); + DEFINE_METHOD(GetHidden, bHidden); + + LunaTapNoteResult() + { + ADD_METHOD( GetTapNoteScore ); + ADD_METHOD( GetTapNoteOffset ); + ADD_METHOD( GetHidden ); + } +}; +LUA_REGISTER_CLASS( TapNoteResult ) + +/** @brief Allow Lua to have access to the HoldNoteResult. */ +class LunaHoldNoteResult: public Luna +{ +public: + DEFINE_METHOD(GetHoldNoteScore, hns); + DEFINE_METHOD(GetLife, fLife); + DEFINE_METHOD(GetOverlappedTime, fOverlappedTime); + DEFINE_METHOD(GetLastHeldBeat, GetLastHeldBeat() ); + DEFINE_METHOD(GetCheckpointsHit, iCheckpointsHit ); + DEFINE_METHOD(GetCheckpointsMissed, iCheckpointsMissed ); + DEFINE_METHOD(GetHeld, bHeld ); + DEFINE_METHOD(GetActive, bActive ); + + LunaHoldNoteResult() + { + ADD_METHOD( GetHoldNoteScore ); + ADD_METHOD( GetLife ); + ADD_METHOD( GetOverlappedTime ); + ADD_METHOD( GetLastHeldBeat ); + ADD_METHOD( GetCheckpointsHit ); + ADD_METHOD( GetCheckpointsMissed ); + ADD_METHOD( GetHeld ); + ADD_METHOD( GetActive ); + } +}; +LUA_REGISTER_CLASS( HoldNoteResult ) + +/** @brief Allow Lua to have access to the TapNote. */ +class LunaTapNote: public Luna +{ +public: + DEFINE_METHOD( GetTapNoteType, type ); + DEFINE_METHOD( GetTapNoteSubType, subType ); + DEFINE_METHOD( GetTapNoteSource, source ); + DEFINE_METHOD( GetPlayerNumber, pn ); + DEFINE_METHOD( GetAttackModifiers, sAttackModifiers ); + DEFINE_METHOD( GetAttackDuration, fAttackDurationSeconds ); + DEFINE_METHOD( GetKeysoundIndex, iKeysoundIndex ); + static int GetHoldDuration( T* p, lua_State* L ) { lua_pushnumber(L, NoteRowToBeat(p->iDuration)); return 1; } + static int GetTapNoteResult( T* p, lua_State* L ) { p->result.PushSelf(L); return 1; } + static int GetHoldNoteResult( T* p, lua_State* L ) { p->HoldResult.PushSelf(L); return 1; } + + LunaTapNote() + { + ADD_METHOD( GetTapNoteType ); + ADD_METHOD( GetTapNoteSubType ); + ADD_METHOD( GetTapNoteSource ); + ADD_METHOD( GetTapNoteResult ); + ADD_METHOD( GetPlayerNumber ); + ADD_METHOD( GetAttackModifiers ); + ADD_METHOD( GetAttackDuration ); + ADD_METHOD( GetKeysoundIndex ); + ADD_METHOD( GetHoldDuration ); + ADD_METHOD( GetHoldNoteResult ); + } +}; +LUA_REGISTER_CLASS( TapNote ) + /* * (c) 2001-2004 Chris Danford, Glenn Maynard * All rights reserved. diff --git a/src/NoteTypes.h b/src/NoteTypes.h index 4cabac1e9c..bd9304828d 100644 --- a/src/NoteTypes.h +++ b/src/NoteTypes.h @@ -31,6 +31,9 @@ struct TapNoteResult // XML XNode* CreateNode() const; void LoadFromNode( const XNode* pNode ); + + // Lua + void PushSelf( lua_State *L ); }; /** @brief The result of holding (or letting go of) a hold note. */ struct HoldNoteResult @@ -73,6 +76,9 @@ struct HoldNoteResult // XML XNode* CreateNode() const; void LoadFromNode( const XNode* pNode ); + + // Lua + void PushSelf( lua_State *L ); }; /** @brief What is the TapNote's core type? */ @@ -87,8 +93,8 @@ enum TapNoteType TapNoteType_Attack, /**< Hitting this note causes an attack to take place. */ TapNoteType_AutoKeysound, /**< A special sound is played when this note crosses the target area. */ TapNoteType_Fake, /**< This arrow can't be scored for or against the player. */ - NUM_TapNoteType, - TapNoteType_Invalid + NUM_TapNoteType, + TapNoteType_Invalid }; const RString& TapNoteTypeToString( TapNoteType tnt ); const RString& TapNoteTypeToLocalizedString( TapNoteType tnt ); @@ -97,11 +103,11 @@ LuaDeclareType( TapNoteType ); /** @brief The list of a TapNote's sub types. */ enum TapNoteSubType { - TapNoteSubType_Hold, /**< The start of a traditional hold note. */ - TapNoteSubType_Roll, /**< The start of a roll note that must be hit repeatedly. */ - //TapNoteSubType_Mine, - NUM_TapNoteSubType, - TapNoteSubType_Invalid + TapNoteSubType_Hold, /**< The start of a traditional hold note. */ + TapNoteSubType_Roll, /**< The start of a roll note that must be hit repeatedly. */ + //TapNoteSubType_Mine, + NUM_TapNoteSubType, + TapNoteSubType_Invalid }; const RString& TapNoteSubTypeToString( TapNoteSubType tnst ); const RString& TapNoteSubTypeToLocalizedString( TapNoteSubType tnst ); @@ -110,10 +116,10 @@ LuaDeclareType( TapNoteSubType ); /** @brief The different places a TapNote could come from. */ enum TapNoteSource { - TapNoteSource_Original, /**< This note is part of the original NoteData. */ - TapNoteSource_Addition, /**< This note is additional note added by a transform. */ - NUM_TapNoteSource, - TapNoteSource_Invalid + TapNoteSource_Original, /**< This note is part of the original NoteData. */ + TapNoteSource_Addition, /**< This note is additional note added by a transform. */ + NUM_TapNoteSource, + TapNoteSource_Invalid }; const RString& TapNoteSourceToString( TapNoteSource tns ); const RString& TapNoteSourceToLocalizedString( TapNoteSource tns ); @@ -145,11 +151,14 @@ struct TapNote // also used for hold_head only: int iDuration; HoldNoteResult HoldResult; - + // XML XNode* CreateNode() const; void LoadFromNode( const XNode* pNode ); + // Lua + void PushSelf( lua_State *L ); + TapNote(): type(TapNoteType_Empty), subType(TapNoteSubType_Invalid), source(TapNoteSource_Original), result(), pn(PLAYER_INVALID), bHopoPossible(false), sAttackModifiers(""), fAttackDurationSeconds(0), @@ -301,7 +310,7 @@ inline float NoteRowToBeat( int iRow ) { return iRow / (float)ROWS_PER_BEAT; } * @brief Convert the note row to note row (returns itself). * @param row the row to convert. */ -static inline int ToNoteRow(int row) { return row; } +static inline int ToNoteRow(int row) { return row; } /** * @brief Convert the beat to note row. @@ -313,7 +322,7 @@ static inline int ToNoteRow(float beat) { return BeatToNoteRow(beat); } * @brief Convert the note row to beat. * @param row the row to convert. */ -static inline float ToBeat(int row) { return NoteRowToBeat(row); } +static inline float ToBeat(int row) { return NoteRowToBeat(row); } /** * @brief Convert the beat row to beat (return itself). diff --git a/src/Player.cpp b/src/Player.cpp index 9c4b6786f3..5bbcdf14b1 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -1464,7 +1464,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace("tap note scoring time."); TapNote &tn = *vTN[0].pTN; - SetHoldJudgment( tn.result.tns, tn.HoldResult.hns, iFirstTrackWithMaxEndRow ); + SetHoldJudgment( tn, iFirstTrackWithMaxEndRow ); HandleHoldScore( tn ); //LOG->Trace("hold result = %s",StringConversion::ToString(tn.HoldResult.hns).c_str()); } @@ -1914,7 +1914,6 @@ void Player::DoTapScoreNone() SendComboMessages( iOldCombo, iOldMissCombo ); - if( m_pLifeMeter ) m_pLifeMeter->HandleTapScoreNone(); // TODO: Remove use of PlayerNumber @@ -1924,7 +1923,7 @@ void Player::DoTapScoreNone() if( PENALIZE_TAP_SCORE_NONE ) { - SetJudgment( TNS_Miss, -1, 0 ); + SetJudgment( BeatToNoteRow( m_pPlayerState->m_Position.m_fSongBeat ), -1, TAP_EMPTY, TNS_Miss, 0 ); // the ScoreKeeper will subtract points later. } } @@ -1960,7 +1959,7 @@ void Player::ScoreAllActiveHoldsLetGo() tn.HoldResult.hns = HNS_LetGo; tn.HoldResult.fLife = 0; - SetHoldJudgment( tn.result.tns, tn.HoldResult.hns, iTrack ); + SetHoldJudgment( tn, iTrack ); HandleHoldScore( tn ); } } @@ -2796,24 +2795,15 @@ void Player::UpdateJudgedRows() if (tn.type == TapNoteType_Empty || tn.type == TapNoteType_Mine || tn.type == TapNoteType_AutoKeysound) continue; - SetJudgment( tn.result.tns, iTrack, tn.result.fTapNoteOffset ); + SetJudgment( iRow, iTrack, tn ); } } else { - vector viColsWithTaps; - for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack ) - { - const TapNote &tn = m_NoteData.GetTapNote( iTrack, iRow ); - if (tn.type == TapNoteType_Tap || tn.type == TapNoteType_Lift || - ( tn.type == TapNoteType_HoldHead && REQUIRE_STEP_ON_HOLD_HEADS ) ) - { - viColsWithTaps.push_back( iTrack ); - }; - } - SetJudgment( lastTNR.tns, m_NoteData.GetFirstTrackWithTapOrHoldHead(iRow), lastTNR.fTapNoteOffset, viColsWithTaps ); + SetJudgment( iRow, m_NoteData.GetFirstTrackWithTapOrHoldHead(iRow), NoteDataWithScoring::LastTapNoteWithResult( m_NoteData, iRow ) ); } HandleTapRowScore( iRow ); + HandleTapRowScore( iRow ); } } } @@ -3245,7 +3235,7 @@ void Player::HandleHoldCheckpoint(int iRow, ChangeLife( iNumHoldsMissedThisRow == 0? TNS_CheckpointHit:TNS_CheckpointMiss ); - SetJudgment( iNumHoldsMissedThisRow == 0? TNS_CheckpointHit:TNS_CheckpointMiss, viColsWithHold[0], 0 ); + SetJudgment( iRow, viColsWithHold[0], TAP_EMPTY, iNumHoldsMissedThisRow == 0? TNS_CheckpointHit:TNS_CheckpointMiss, 0 ); } void Player::HandleHoldScore( const TapNote &tn ) @@ -3330,7 +3320,7 @@ void Player::SetMineJudgment( TapNoteScore tns , int iTrack ) } } -void Player::SetJudgment( TapNoteScore tns, int iTrack, float fTapNoteOffset, vector viCols ) +void Player::SetJudgment( int iRow, int iTrack, const TapNote &tn, TapNoteScore tns, float fTapNoteOffset ) { if( m_bSendJudgmentAndComboMessages ) { @@ -3340,17 +3330,44 @@ void Player::SetJudgment( TapNoteScore tns, int iTrack, float fTapNoteOffset, ve msg.SetParam( "FirstTrack", iTrack ); msg.SetParam( "TapNoteScore", tns ); msg.SetParam( "Early", fTapNoteOffset < 0.0f ); - msg.SetParam( "TapNoteOffset", fTapNoteOffset ); - msg.SetParam( "Tracks" , viCols ); + msg.SetParam( "TapNoteOffset", tn.result.fTapNoteOffset ); + + Lua* L= LUA->Get(); + lua_createtable( L, 0, m_NoteData.GetNumTracks() ); // TapNotes this row + lua_createtable( L, 0, m_NoteData.GetNumTracks() ); // HoldHeads of tracks held at this row. + + for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack ) + { + NoteData::iterator tn = m_NoteData.FindTapNote(iTrack, iRow); + if( tn != m_NoteData.end(iTrack) ) + { + tn->second.PushSelf(L); + lua_rawseti(L, -3, iTrack + 1); + } + else + { + int iHeadRow; + if( m_NoteData.IsHoldNoteAtRow( iTrack, iRow, &iHeadRow ) ) + { + NoteData::iterator hold = m_NoteData.FindTapNote(iTrack, iHeadRow); + hold->second.PushSelf(L); + lua_rawseti(L, -2, iTrack + 1); + } + } + } + msg.SetParamFromStack( L, "Holds" ); + msg.SetParamFromStack( L, "Notes" ); + + LUA->Release( L ); MESSAGEMAN->Broadcast( msg ); } } -void Player::SetHoldJudgment( TapNoteScore tns, HoldNoteScore hns, int iTrack ) +void Player::SetHoldJudgment( TapNote &tn, int iTrack ) { ASSERT( iTrack < (int)m_vpHoldJudgment.size() ); if( m_vpHoldJudgment[iTrack] ) - m_vpHoldJudgment[iTrack]->SetHoldJudgment( hns ); + m_vpHoldJudgment[iTrack]->SetHoldJudgment( tn.HoldResult.hns ); if( m_bSendJudgmentAndComboMessages ) { @@ -3359,8 +3376,13 @@ void Player::SetHoldJudgment( TapNoteScore tns, HoldNoteScore hns, int iTrack ) msg.SetParam( "MultiPlayer", m_pPlayerState->m_mp ); msg.SetParam( "FirstTrack", iTrack ); msg.SetParam( "NumTracks", (int)m_vpHoldJudgment.size() ); - msg.SetParam( "TapNoteScore", tns ); - msg.SetParam( "HoldNoteScore", hns ); + msg.SetParam( "TapNoteScore", tn.result.tns ); + msg.SetParam( "HoldNoteScore", tn.HoldResult.hns ); + + Lua* L = LUA->Get(); + tn.PushSelf(L); + msg.SetParamFromStack( L, "TapNote" ); + MESSAGEMAN->Broadcast( msg ); } } diff --git a/src/Player.h b/src/Player.h index a4b8b486f5..9d75b98235 100644 --- a/src/Player.h +++ b/src/Player.h @@ -132,9 +132,9 @@ protected: void PlayKeysound( const TapNote &tn, TapNoteScore score ); void SetMineJudgment( TapNoteScore tns , int iTrack ); - void SetJudgment( TapNoteScore tns, int iFirstTrack, float fTapNoteOffset ) { vector viCols (1,iFirstTrack); SetJudgment( tns, iFirstTrack, fTapNoteOffset, viCols ); } - void SetJudgment( TapNoteScore tns, int iFirstTrack, float fTapNoteOffset, vector viCols ); // -1 if no track as in TNS_Miss - void SetHoldJudgment( TapNoteScore tns, HoldNoteScore hns, int iTrack ); + void SetJudgment( int iRow, int iFirstTrack, const TapNote &tn ) { SetJudgment( iRow, iFirstTrack, tn, tn.result.tns, tn.result.fTapNoteOffset ); } + void SetJudgment( int iRow, int iFirstTrack, const TapNote &tn, TapNoteScore tns, float fTapNoteOffset ); // -1 if no track as in TNS_Miss + void SetHoldJudgment( TapNote &tn, int iTrack ); void SetCombo( int iCombo, int iMisses ); void ChangeLife( TapNoteScore tns ); From ec23dcb5039d39be87152d4a39c553954226538b Mon Sep 17 00:00:00 2001 From: sigatrev Date: Sat, 6 Sep 2014 15:40:46 -0500 Subject: [PATCH 2/8] fix major typo oops... --- src/Player.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Player.cpp b/src/Player.cpp index 5bbcdf14b1..ea07357e20 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -2803,7 +2803,6 @@ void Player::UpdateJudgedRows() SetJudgment( iRow, m_NoteData.GetFirstTrackWithTapOrHoldHead(iRow), NoteDataWithScoring::LastTapNoteWithResult( m_NoteData, iRow ) ); } HandleTapRowScore( iRow ); - HandleTapRowScore( iRow ); } } } From 1da2132956748d9c713ea4f6ef734015682fa030 Mon Sep 17 00:00:00 2001 From: Forest Date: Mon, 8 Sep 2014 11:01:29 -0700 Subject: [PATCH 3/8] Avoid spaces in the productID / installation directory name. The productID is used as the installation directory name, and a space character within it can be problematic for some packaging tools. We therefore use a - instead. --- Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 7da514dda1..d04ddb2df3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,8 @@ ACLOCAL_AMFLAGS = -I autoconf/m4 ## Black magic (read: sed) for getting the product ID as defined in code, not by the autotools. ## Quotes are making vim's highlighting of this even worse, so just escape everything, ## including the escapes. Make it lowercase to match ArchHooks::MountInitialFileSystems(). -productID := $(shell sed -nr /define\\s+PRODUCT_ID_BARE/\{s/.*define\\s+PRODUCT_ID_BARE\\s+\(.+\)/\\1/\;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/\;p\;q\} $(srcdir)/src/ProductInfo.h) +## Replace space with - so package build tools won't choke on the installation directory. +productID := $(shell sed -nr /define\\s+PRODUCT_ID_BARE/\{s/.*define\\s+PRODUCT_ID_BARE\\s+\(.+\)/\\1/\;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ\ /abcdefghijklmnopqrstuvwxyz-/\;p\;q\} $(srcdir)/src/ProductInfo.h) installFiles = src/stepmania if HAVE_GTK From e8a56b17e39a0f7c1b4056e160730d9c946ea557 Mon Sep 17 00:00:00 2001 From: Forest Date: Mon, 8 Sep 2014 11:09:31 -0700 Subject: [PATCH 4/8] Prepend $(DESTDIR) to install directories, for packaging tools. --- Makefile.am | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index d04ddb2df3..0835b739e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -27,14 +27,14 @@ dist-hook: SMData cp -r -t "$(distdir)" $(installFiles) install-exec-hook: - mkdir -p "$(prefix)/$(productID)" - $(INSTALL) $(installFiles) "$(prefix)/$(productID)" + mkdir -p "$(DESTDIR)$(prefix)/$(productID)" + $(INSTALL) $(installFiles) "$(DESTDIR)$(prefix)/$(productID)" install-data-local: - cp -r -t "$(prefix)/$(productID)" $(installData) - mkdir -p "$(prefix)/$(productID)/Songs" + cp -r -t "$(DESTDIR)$(prefix)/$(productID)" $(installData) + mkdir -p "$(DESTDIR)$(prefix)/$(productID)/Songs" uninstall-hook: - rm -f "$(prefix)/$(productID)/stepmania" - rm -f "$(prefix)/$(productID)/GtkModule.so" + rm -f "$(DESTDIR)$(prefix)/$(productID)/stepmania" + rm -f "$(DESTDIR)$(prefix)/$(productID)/GtkModule.so" # todo: properly remove data From bdaf0542f8a3d246365d2b3705a9c19c546f9c09 Mon Sep 17 00:00:00 2001 From: Forest Date: Mon, 8 Sep 2014 11:11:28 -0700 Subject: [PATCH 5/8] Make sure the target dir exists before copying to it. Parallel builds (make -j4) were failing because the installation directory wasn't guaranteed to exist before we tried copying files to it. --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 0835b739e0..271f0346ed 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,8 +31,8 @@ install-exec-hook: $(INSTALL) $(installFiles) "$(DESTDIR)$(prefix)/$(productID)" install-data-local: - cp -r -t "$(DESTDIR)$(prefix)/$(productID)" $(installData) mkdir -p "$(DESTDIR)$(prefix)/$(productID)/Songs" + cp -r -t "$(DESTDIR)$(prefix)/$(productID)" $(installData) uninstall-hook: rm -f "$(DESTDIR)$(prefix)/$(productID)/stepmania" From bcb258911498bc92c19d11efa7778982826625ee Mon Sep 17 00:00:00 2001 From: Kyzentun Date: Wed, 10 Sep 2014 02:44:49 -0600 Subject: [PATCH 6/8] Fixed endless courses to make them repick on repeats and not crash after repeating. --- src/Course.cpp | 8 +++-- src/GameState.cpp | 5 ++++ src/GameState.h | 2 ++ src/ScreenGameplay.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/Course.cpp b/src/Course.cpp index 73528353e0..8b291d7b6a 100644 --- a/src/Course.cpp +++ b/src/Course.cpp @@ -404,6 +404,9 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) trail.Init(); // XXX: Why are beginner and challenge excluded here? -Wolfman2000 + // No idea, probably an obsolete design decision from ITG, removing + // exclusion here, but there's some other area that prevents it too. -Kyz + /* switch( cd ) { case Difficulty_Beginner: @@ -412,6 +415,7 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) return false; default: break; } + */ // Construct a new Trail, add it to the cache, then return it. // Different seed for each course, but the same for the whole round: @@ -848,9 +852,9 @@ bool Course::CourseHasBestOrWorst() const { FOREACH_CONST( CourseEntry, m_vEntries, e ) { - if( e->iChooseIndex == SongSort_MostPlays && e->iChooseIndex != -1 ) + if( e->songSort == SongSort_MostPlays && e->iChooseIndex != -1 ) return true; - if( e->iChooseIndex == SongSort_FewestPlays && e->iChooseIndex != -1 ) + if( e->songSort == SongSort_FewestPlays && e->iChooseIndex != -1 ) return true; } diff --git a/src/GameState.cpp b/src/GameState.cpp index eb993a701e..370cdb6ef3 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -2109,6 +2109,11 @@ Difficulty GameState::GetHardestStepsDifficulty() const return dc; } +void GameState::SetNewStageSeed() +{ + m_iStageSeed= rand(); +} + bool GameState::IsEventMode() const { return m_bTemporaryEventMode || PREFSMAN->m_bEventMode; diff --git a/src/GameState.h b/src/GameState.h index 3b6bf60345..3c463e0e69 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -117,6 +117,8 @@ public: int m_iGameSeed, m_iStageSeed; RString m_sStageGUID; + void SetNewStageSeed(); + /** * @brief Determine if a second player can join in at this time. * @return true if a player can still enter the game, false otherwise. */ diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index aff5d2b36a..2c1a96e36e 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -2618,6 +2618,72 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) pi->m_pLifeMeter->OnSongEnded(); } + // If this is a repeating course, and we're at the end of it, repick and + // add new songs to the players' step and song queues. + if(GAMESTATE->IsCourseMode() && GAMESTATE->m_pCurCourse && + GAMESTATE->m_pCurCourse->m_bRepeat && + GAMESTATE->GetCourseSongIndex() >= (int)m_apSongsQueue.size()-1) + { + Course* course= GAMESTATE->m_pCurCourse; + ASSERT(course != NULL); + // Need to store these so they can be used to refetch the players' + // trails after they're invalidated. + vector trail_sts; + vector trail_cds; + FOREACH_EnabledPlayerInfo(m_vPlayerInfo, pi) + { + Trail* trail= GAMESTATE->m_pCurTrail[pi->GetStepsAndTrailIndex()]; + ASSERT(trail != NULL); + trail_sts.push_back(trail->m_StepsType); + trail_cds.push_back(trail->m_CourseDifficulty); + } + // Set a new stage seed so the order will be different. + GAMESTATE->SetNewStageSeed(); + course->InvalidateTrailCache(); + course->RegenerateNonFixedTrails(); + size_t info_id= 0; // Can't use the player number in the playerinfo + // because it won't match up in 2-player. + FOREACH_EnabledPlayerInfo(m_vPlayerInfo, pi) + { + Trail* trail= course->GetTrail(trail_sts[info_id], trail_cds[info_id]); + ASSERT(trail != NULL); + GAMESTATE->m_pCurTrail[pi->m_pn].Set(trail); + ++info_id; + } + PlayerNumber master_pn = GAMESTATE->GetMasterPlayerNumber(); + Trail *master_trail= GAMESTATE->m_pCurTrail[master_pn]; + ASSERT(master_trail != NULL); + FOREACH_CONST(TrailEntry, master_trail->m_vEntries, entry) + { + ASSERT(entry->pSong != NULL); + m_apSongsQueue.push_back(entry->pSong); + STATSMAN->m_CurStageStats.m_vpPossibleSongs.push_back(entry->pSong); + } + FOREACH_EnabledPlayerInfo(m_vPlayerInfo, pi) + { + Trail* trail= GAMESTATE->m_pCurTrail[pi->GetStepsAndTrailIndex()]; + ASSERT(trail != NULL); + FOREACH_CONST(TrailEntry, trail->m_vEntries, entry) + { + ASSERT(entry->pSteps != NULL); + pi->m_vpStepsQueue.push_back(entry->pSteps); + AttackArray a; + entry->GetAttackArray(a); + pi->m_asModifiersQueue.push_back(a); + pi->GetPlayerStageStats()->m_vpPossibleSteps.push_back(entry->pSteps); + } + // In a survival course, override stored mods + if(course->GetCourseType() == COURSE_TYPE_SURVIVAL && + SURVIVAL_MOD_OVERRIDE) + { + pi->GetPlayerState()->m_PlayerOptions.FromString(ModsLevel_Stage, + "clearall," + CommonMetrics::DEFAULT_NOTESKIN_NAME.GetValue() + + "," + CommonMetrics::DEFAULT_MODIFIERS.GetValue()); + pi->GetPlayerState()->RebuildPlayerOptionsFromActiveAttacks(); + } + } + } + GAMESTATE->m_bLoadingNextSong = true; MESSAGEMAN->Broadcast( "BeforeLoadingNextCourseSong" ); m_NextSong.Reset(); From 8b866c9584dcd85ff3bcc4a87d935a2f4e79c4b0 Mon Sep 17 00:00:00 2001 From: Forest Date: Thu, 11 Sep 2014 04:03:32 -0700 Subject: [PATCH 7/8] Remove the execute bit from non-executable files. Fixes stepmania/stepmania#300. --- Themes/_fallback/Languages/pl.ini | 0 .../Graphics/LifeMeterBattery lives/_lives 1x10.png | Bin .../Graphics/LifeMeterBattery lives/default.lua | 0 Themes/default/Languages/pl.ini | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Themes/_fallback/Languages/pl.ini mode change 100755 => 100644 Themes/default/Graphics/LifeMeterBattery lives/_lives 1x10.png mode change 100755 => 100644 Themes/default/Graphics/LifeMeterBattery lives/default.lua mode change 100755 => 100644 Themes/default/Languages/pl.ini diff --git a/Themes/_fallback/Languages/pl.ini b/Themes/_fallback/Languages/pl.ini old mode 100755 new mode 100644 diff --git a/Themes/default/Graphics/LifeMeterBattery lives/_lives 1x10.png b/Themes/default/Graphics/LifeMeterBattery lives/_lives 1x10.png old mode 100755 new mode 100644 diff --git a/Themes/default/Graphics/LifeMeterBattery lives/default.lua b/Themes/default/Graphics/LifeMeterBattery lives/default.lua old mode 100755 new mode 100644 diff --git a/Themes/default/Languages/pl.ini b/Themes/default/Languages/pl.ini old mode 100755 new mode 100644 From b20fe48bbac1693fa586259fc83e3ad7ca39f9c1 Mon Sep 17 00:00:00 2001 From: freem Date: Thu, 11 Sep 2014 17:03:39 -0500 Subject: [PATCH 8/8] fix some of the errors in the luadoc; doc returns --- Docs/Luadoc/LuaDocumentation.xml | 52 ++++++++++++++++---------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index 912176d889..addb2faaa4 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -453,7 +453,7 @@ save yourself some time, copy this for undocumented things: [02 Colors.lua] Modifies the saturation of the specified color - + Saves a screenshot. If pn is nil, saves to the machine's Screenshots dir, otherwise saves to the profile's Screenshots dir. Saves as jpg if compress is true, or png if compress is false. The screenshot is signed if sign is true. prefix and suffix are optional strings to add to the beginning and end of the filename.
Returns success and full path of the resulting screenshot.
@@ -648,56 +648,56 @@ save yourself some time, copy this for undocumented things: Updates ArrowEffects, which sets current values for Tornado, Invert, and Beat. - + Returns the Y Offset of a note in column iCol at beat fNoteBeat for the provided PlayerState. Y Offset is affected by Speed mods and Accel mods, and impacts most other arrow effects. - + Returns the Y position of a note in column iCol with a Y offset of fYOffset for the provided PlayerState.
fYReverseOffsetPixels is the separation between targets with and without reverse. This argument is optional and will pull defaults from the metrics for [Player]
- + Returns the Y offset of a note in column iCol with a Y position of fYPos for the provided PlayerState.
fYReverseOffsetPixels is the separation between targets with and without reverse. This argument is optional and will pull defaults from the metrics for [Player]
- + Returns the X position of a note in column iCol with a Y offset of fYOffset for the provided PlayerState. - + Returns the Z position of a note in column iCol with a Y offset of fYOffset for the provided PlayerState. - + Returns the X rotation of a note with a Y offset of fYOffset for the provided PlayerState. - + Returns the Y rotation of a note with a Y offset of fYOffset for the provided PlayerState. - + Returns the Z rotation of a note at beat fNoteBeat for the provided PlayerState.
bIsHoldHead is an optional argument which defaults to false. If true, this function will return 0 if the [ArrowEffects] metric DizzyHoldHeads is false.
- + Returns the Z rotation of the receptors for the provided PlayerState. - + Returns the Alpha of a note in column iCol with a Y offset of fYOffset for the provided PlayerState.
fPercentFadeToFail is optional and defaults to -1.
fYReverseOffsetPixels is the separation between targets with and without reverse. This argument is optional and will pull defaults from the metrics for [Player]
fDrawDistanceBeforeTargetsPixels is optional and will pull defaults from the [Player] metric DrawDistanceBeforeTargetsPixels
fFadeInPercentOfDrawFar is optional and will pull defaults from the [NoteField] metric FadeBeforeTargetsPercent
- + Returns the Glow of a note in column iCol with a Y offset of fYOffset for the provided PlayerState. The arguments are the same as for GetAlpha. - + Returns the brightness of a note at beat fNoteBeat for the provided PlayerState. - + Returns true if any arrow effects for the provided PlayerState require the z buffer. - + Returns the zoom of a note for the provided PlayerState. - + Returns the FrameWidthScale of a hold part with a Y offset of fYOffset for the provided PlayerState.
fOverlappedTime is optional and will default to 0.
@@ -755,7 +755,7 @@ save yourself some time, copy this for undocumented things: Tries to read the file at sPath. If successful, it returns the file's contents. If unsuccessful, it returns two values: nil and "error".
- + Reports the error through the error reporting system. error_type is the type used for the dialog that is presented, a dialog will not appear for a type the user has chosen to ignore.
error is optional an defaults to "Script error occurred.". error_type is optional and defaults to "LUA_ERROR".
@@ -4630,7 +4630,7 @@ save yourself some time, copy this for undocumented things: Returns the StyleType for this Style. - + Returns a table containing the Track, XOffset, and Name of the column. @@ -4645,19 +4645,19 @@ save yourself some time, copy this for undocumented things:
- Returns the of the Tap Note. + Returns the of the Tap Note. - Returns the of the Tap Note. + Returns the of the Tap Note. - Returns the of the Tap Note. + Returns the of the Tap Note. - Returns the of the Tap Note. + Returns the of the Tap Note. - Returns the of the Tap Note. Relevant for routine steps. + Returns the of the Tap Note. Relevant for routine steps. Returns the Attack Modifiers of the Tap Note. @@ -4672,12 +4672,12 @@ save yourself some time, copy this for undocumented things: Returns the Hold Duration of the Tap Note in beats. - Returns the of the Tap Note. + Returns the of the Tap Note. - Returns the of the Tap Note. + Returns the of the Tap Note. Returns the TapNotOffset of the Tap Note. @@ -4688,7 +4688,7 @@ save yourself some time, copy this for undocumented things: - Returns the of the Hold Note. + Returns the of the Hold Note. Returns the life of the Hold Note.