This commit is contained in:
Jonathan Payne
2014-09-13 16:29:28 -07:00
15 changed files with 376 additions and 94 deletions
+27
View File
@@ -1641,6 +1641,33 @@
<Function name='LockedDifficulty'/> <Function name='LockedDifficulty'/>
<Function name='NeedsZoomOutWith2Players'/> <Function name='NeedsZoomOutWith2Players'/>
</Class> </Class>
<Class name='TapNote'>
<Function name='GetTapNoteType'/>
<Function name='GetTapNoteSubType'/>
<Function name='GetTapNoteSource'/>
<Function name='GetTapNoteResult'/>
<Function name='GetPlayerNumber'/>
<Function name='GetAttackModifiers'/>
<Function name='GetAttackDuration'/>
<Function name='GetKeysoundIndex'/>
<Function name='GetHoldDuration'/>
<Function name='GetHoldNoteResult'/>
</Class>
<Class name='TapNoteResult'>
<Function name='GetTapNoteScore'/>
<Function name='GetTapNoteOffset'/>
<Function name='GetHidden'/>
</Class>
<Class name='HoldNoteResult'>
<Function name='GetHoldNoteScore'/>
<Function name='GetLife'/>
<Function name='GetOverlappedTime'/>
<Function name='GetLastHeldBeat'/>
<Function name='GetCheckpointsHit'/>
<Function name='GetCheckpointsMissed'/>
<Function name='GetHeld'/>
<Function name='GetActive'/>
</Class>
<Class base='ActorFrame' name='TextBanner'> <Class base='ActorFrame' name='TextBanner'>
<Function name='Load'/> <Function name='Load'/>
<Function name='SetFromSong'/> <Function name='SetFromSong'/>
+87 -18
View File
@@ -453,7 +453,7 @@ save yourself some time, copy this for undocumented things:
<Function name='Saturation' theme='_fallback' return='color' arguments='color c, float percent'> <Function name='Saturation' theme='_fallback' return='color' arguments='color c, float percent'>
[02 Colors.lua] Modifies the saturation of the specified color [02 Colors.lua] Modifies the saturation of the specified color
</Function> </Function>
<Function name='SaveScreenshot' return= 'bool, string' arguments='PlayerNumber pn, bool compress, bool sign, string prefix, string suffix'> <Function name='SaveScreenshot' return='bool, string' arguments='PlayerNumber pn, bool compress, bool sign, string prefix, string suffix'>
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.<br/> 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.<br/>
Returns success and full path of the resulting screenshot. Returns success and full path of the resulting screenshot.
</Function> </Function>
@@ -648,56 +648,56 @@ save yourself some time, copy this for undocumented things:
<Function name='Update' return='void' arguments=''> <Function name='Update' return='void' arguments=''>
Updates ArrowEffects, which sets current values for Tornado, Invert, and Beat. Updates ArrowEffects, which sets current values for Tornado, Invert, and Beat.
</Function> </Function>
<Function name='GetYOffset' return='float fYOffset' arguments='PlayerState ps, int iCol, float fNoteBeat'> <Function name='GetYOffset' return='float' arguments='PlayerState ps, int iCol, float fNoteBeat'>
Returns the Y Offset of a note in column <code>iCol</code> at beat <code>fNoteBeat</code> for the provided PlayerState. Y Offset is affected by Speed mods and Accel mods, and impacts most other arrow effects. Returns the Y Offset of a note in column <code>iCol</code> at beat <code>fNoteBeat</code> for the provided PlayerState. Y Offset is affected by Speed mods and Accel mods, and impacts most other arrow effects.
</Function> </Function>
<Function name='GetYPos' return='float fYPos' arguments='PlayerState ps, int iCol, float fYOffset, float fYReverseOffsetPixels'> <Function name='GetYPos' return='float' arguments='PlayerState ps, int iCol, float fYOffset, float fYReverseOffsetPixels'>
Returns the Y position of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState.<br/> Returns the Y position of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState.<br/>
<code>fYReverseOffsetPixels</code> is the separation between targets with and without reverse. This argument is optional and will pull defaults from the metrics for <code>[Player]</code> <code>fYReverseOffsetPixels</code> is the separation between targets with and without reverse. This argument is optional and will pull defaults from the metrics for <code>[Player]</code>
</Function> </Function>
<Function name='GetYOffsetFromYPos' return='float fYOffset' arguments='PlayerState ps, int iCol, float fYPos, float fYReverseOffsetPixels'> <Function name='GetYOffsetFromYPos' return='float' arguments='PlayerState ps, int iCol, float fYPos, float fYReverseOffsetPixels'>
Returns the Y offset of a note in column <code>iCol</code> with a Y position of <code>fYPos</code> for the provided PlayerState.<br/> Returns the Y offset of a note in column <code>iCol</code> with a Y position of <code>fYPos</code> for the provided PlayerState.<br/>
<code>fYReverseOffsetPixels</code> is the separation between targets with and without reverse. This argument is optional and will pull defaults from the metrics for <code>[Player]</code> <code>fYReverseOffsetPixels</code> is the separation between targets with and without reverse. This argument is optional and will pull defaults from the metrics for <code>[Player]</code>
</Function> </Function>
<Function name='GetXPos' return='float fXPos' arguments='PlayerState ps, int iCol, float fYOffset'> <Function name='GetXPos' return='float' arguments='PlayerState ps, int iCol, float fYOffset'>
Returns the X position of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState. Returns the X position of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState.
</Function> </Function>
<Function name='GetZPos' return='float fZPos' arguments='PlayerState ps, int iCol, float fYOffset'> <Function name='GetZPos' return='float' arguments='PlayerState ps, int iCol, float fYOffset'>
Returns the Z position of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState. Returns the Z position of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState.
</Function> </Function>
<Function name='GetRotationX' return='float fRotationX' arguments='PlayerState ps, float fYOffset'> <Function name='GetRotationX' return='float' arguments='PlayerState ps, float fYOffset'>
Returns the X rotation of a note with a Y offset of <code>fYOffset</code> for the provided PlayerState. Returns the X rotation of a note with a Y offset of <code>fYOffset</code> for the provided PlayerState.
</Function> </Function>
<Function name='GetRotationY' return='float fRotationY' arguments='PlayerState ps, float fYOffset'> <Function name='GetRotationY' return='float' arguments='PlayerState ps, float fYOffset'>
Returns the Y rotation of a note with a Y offset of <code>fYOffset</code> for the provided PlayerState. Returns the Y rotation of a note with a Y offset of <code>fYOffset</code> for the provided PlayerState.
</Function> </Function>
<Function name='GetRotationZ' return='float fRotationZ' arguments='PlayerState ps, float fNoteBeat, bool bIsHoldHead'> <Function name='GetRotationZ' return='float' arguments='PlayerState ps, float fNoteBeat, bool bIsHoldHead'>
Returns the Z rotation of a note at beat <code>fNoteBeat</code> for the provided PlayerState.<br/> Returns the Z rotation of a note at beat <code>fNoteBeat</code> for the provided PlayerState.<br/>
<code>bIsHoldHead</code> is an optional argument which defaults to false. If true, this function will return <code>0</code> if the [ArrowEffects] metric <code>DizzyHoldHeads</code> is false. <code>bIsHoldHead</code> is an optional argument which defaults to false. If true, this function will return <code>0</code> if the [ArrowEffects] metric <code>DizzyHoldHeads</code> is false.
</Function> </Function>
<Function name='ReceptorGetRotationZ' return='float fRotationZ' arguments='PlayerState ps'> <Function name='ReceptorGetRotationZ' return='float' arguments='PlayerState ps'>
Returns the Z rotation of the receptors for the provided PlayerState. Returns the Z rotation of the receptors for the provided PlayerState.
</Function> </Function>
<Function name='GetAlpha' return='float fAlpha' arguments='PlayerState ps, int iCol, float fYOffset, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar'> <Function name='GetAlpha' return='float' arguments='PlayerState ps, int iCol, float fYOffset, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar'>
Returns the Alpha of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState.<br/> Returns the Alpha of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState.<br/>
<code>fPercentFadeToFail</code> is optional and defaults to -1.<br/> <code>fPercentFadeToFail</code> is optional and defaults to -1.<br/>
<code>fYReverseOffsetPixels</code> is the separation between targets with and without reverse. This argument is optional and will pull defaults from the metrics for <code>[Player]</code><br/> <code>fYReverseOffsetPixels</code> is the separation between targets with and without reverse. This argument is optional and will pull defaults from the metrics for <code>[Player]</code><br/>
<code>fDrawDistanceBeforeTargetsPixels</code> is optional and will pull defaults from the <code>[Player]</code> metric <code>DrawDistanceBeforeTargetsPixels</code><br/> <code>fDrawDistanceBeforeTargetsPixels</code> is optional and will pull defaults from the <code>[Player]</code> metric <code>DrawDistanceBeforeTargetsPixels</code><br/>
<code>fFadeInPercentOfDrawFar</code> is optional and will pull defaults from the <code>[NoteField]</code> metric <code>FadeBeforeTargetsPercent</code><br/> <code>fFadeInPercentOfDrawFar</code> is optional and will pull defaults from the <code>[NoteField]</code> metric <code>FadeBeforeTargetsPercent</code><br/>
</Function> </Function>
<Function name='GetGlow' return='float fGlow' arguments='PlayerState ps, int iCol, float fYOffset, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar'> <Function name='GetGlow' return='float' arguments='PlayerState ps, int iCol, float fYOffset, float fPercentFadeToFail, float fYReverseOffsetPixels, float fDrawDistanceBeforeTargetsPixels, float fFadeInPercentOfDrawFar'>
Returns the Glow of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState. The arguments are the same as for GetAlpha. Returns the Glow of a note in column <code>iCol</code> with a Y offset of <code>fYOffset</code> for the provided PlayerState. The arguments are the same as for GetAlpha.
</Function> </Function>
<Function name='GetBrightness' return='float fBrightness' arguments='PlayerState ps, float fNoteBeat'> <Function name='GetBrightness' return='float' arguments='PlayerState ps, float fNoteBeat'>
Returns the brightness of a note at beat <code>fNoteBeat</code> for the provided PlayerState. Returns the brightness of a note at beat <code>fNoteBeat</code> for the provided PlayerState.
</Function> </Function>
<Function name='NeedZBuffer' return='bool bNeedZBuffer' arguments='PlayerState ps'> <Function name='NeedZBuffer' return='bool' arguments='PlayerState ps'>
Returns true if any arrow effects for the provided PlayerState require the z buffer. Returns true if any arrow effects for the provided PlayerState require the z buffer.
</Function> </Function>
<Function name='GetZoom' return='float fZoom' arguments='PlayerState ps'> <Function name='GetZoom' return='float' arguments='PlayerState ps'>
Returns the zoom of a note for the provided PlayerState. Returns the zoom of a note for the provided PlayerState.
</Function> </Function>
<Function name='GetFrameWidthScale' return='float fFameWidthScale' arguments='PlayerState ps, float fYOffset, fOverlappedTime'> <Function name='GetFrameWidthScale' return='float' arguments='PlayerState ps, float fYOffset, fOverlappedTime'>
Returns the FrameWidthScale of a hold part with a Y offset of <code>fYOffset</code> for the provided PlayerState.<br/> <code>fOverlappedTime</code> is optional and will default to 0. Returns the FrameWidthScale of a hold part with a Y offset of <code>fYOffset</code> for the provided PlayerState.<br/> <code>fOverlappedTime</code> is optional and will default to 0.
</Function> </Function>
</Namespace> </Namespace>
@@ -755,7 +755,7 @@ save yourself some time, copy this for undocumented things:
Tries to read the file at <code>sPath</code>. If successful, it returns the file's contents. Tries to read the file at <code>sPath</code>. If successful, it returns the file's contents.
If unsuccessful, it returns two values: <code>nil</code> and <code>"error"</code>. If unsuccessful, it returns two values: <code>nil</code> and <code>"error"</code>.
</Function> </Function>
<Function name='ReportScriptError' return='' arguments= 'string error, string error_type'> <Function name='ReportScriptError' return='void' arguments='string error, string error_type'>
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.<br/> 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.<br/>
error is optional an defaults to "Script error occurred.". error_type is optional and defaults to "LUA_ERROR". error is optional an defaults to "Script error occurred.". error_type is optional and defaults to "LUA_ERROR".
</Function> </Function>
@@ -4630,7 +4630,7 @@ save yourself some time, copy this for undocumented things:
<Function name='GetStyleType' return='StyleType' arguments=''> <Function name='GetStyleType' return='StyleType' arguments=''>
Returns the StyleType for this Style. Returns the StyleType for this Style.
</Function> </Function>
<Function name='GetColumnInfo' return='{Track= int, XOffset= int, Name= string}' arguments='int column'> <Function name='GetColumnInfo' return='{int, int, string}' arguments='int column'>
Returns a table containing the Track, XOffset, and Name of the column. Returns a table containing the Track, XOffset, and Name of the column.
</Function> </Function>
<Function name='GetColumnDrawOrder' return='int' arguments='int column'> <Function name='GetColumnDrawOrder' return='int' arguments='int column'>
@@ -4643,6 +4643,75 @@ save yourself some time, copy this for undocumented things:
Returns <code>true</code> if the Style needs to be zoomed out with two players. Returns <code>true</code> if the Style needs to be zoomed out with two players.
</Function> </Function>
</Class> </Class>
<Class name='TapNote'>
<Function name='GetTapNoteType' return='TapNoteType' arguments=''>
Returns the <Link class='TapNoteType' /> of the Tap Note.
</Function>
<Function name='GetTapNoteSubType' return='TapNoteSubType' arguments=''>
Returns the <Link class='TapNoteSubType' /> of the Tap Note.
</Function>
<Function name='GetTapNoteSource' return='TapNoteSource' arguments=''>
Returns the <Link class='TapNoteSource' /> of the Tap Note.
</Function>
<Function name='GetTapNoteResult' return='TapNoteResult' arguments=''>
Returns the <Link class='TapNoteResult' /> of the Tap Note.
</Function>
<Function name='GetPlayerNumber' return='PlayerNumber' arguments=''>
Returns the <Link class='PlayerNumber' /> of the Tap Note. Relevant for routine steps.
</Function>
<Function name='GetAttackModifiers' return='string' arguments=''>
Returns the Attack Modifiers of the Tap Note.
</Function>
<Function name='GetAttackDuration' return='float' arguments=''>
Returns the Attack Duration of the Tap Note in seconds.
</Function>
<Function name='GetKeysoundIndex' return='int' arguments=''>
Returns the Keysound Index of the Tap Note.
</Function>
<Function name='GetHoldDuration' return='float' arguments=''>
Returns the Hold Duration of the Tap Note in beats.
</Function>
<Function name='GetHoldNoteResult' return='HoldNoteResult' arguments=''>
Returns the <Link class='HoldNoteResult' /> of the Tap Note.
</Function>
</Class>
<Class name='TapNoteResult'>
<Function name='GetTapNoteScore' return='TapNoteScore' arguments=''>
Returns the <Link class='TapNoteScore' /> of the Tap Note.
</Function>
<Function name='GetTapNoteOffset' return='float' arguments=''>
Returns the TapNotOffset of the Tap Note.
</Function>
<Function name='GetHidden' return='bool' arguments=''>
Returns true if the Tap Note was judged with a result that would stop it from drawing.
</Function>
</Class>
<Class name='HoldNoteResult'>
<Function name='GetHoldNoteScore'>
Returns the <Link class='HoldNoteScore' /> of the Hold Note.
</Function>
<Function name='GetLife' return='float' arguments=''>
Returns the life of the Hold Note.
</Function>
<Function name='GetOverlappedTime' return='float' arguments=''>
Returns the amount of time the hold has overlapped the target.
</Function>
<Function name='GetLastHeldBeat' return='float' arguments=''>
Returns the last beat the Hold Note was held.
</Function>
<Function name='GetCheckpointsHit' return='int' arguments=''>
Returns the number of checkpoints hit.
</Function>
<Function name='GetCheckpointsMissed' return='int' arguments=''>
Returns the number of checkpoints missed.
</Function>
<Function name='GetHeld' return='bool' arguments=''>
Returns true if the note was initiated and is being held.
</Function>
<Function name='GetActive' return='bool' arguments=''>
Returns true if the note was initiated.
</Function>
</Class>
<Class name='TextBanner'> <Class name='TextBanner'>
<Function name='Load' return='void' arguments='string sMetricsGroup'> <Function name='Load' return='void' arguments='string sMetricsGroup'>
Loads the TextBanner from the specified metrics group. Loads the TextBanner from the specified metrics group.
+8 -7
View File
@@ -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. ## 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, ## Quotes are making vim's highlighting of this even worse, so just escape everything,
## including the escapes. Make it lowercase to match ArchHooks::MountInitialFileSystems(). ## 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 installFiles = src/stepmania
if HAVE_GTK if HAVE_GTK
@@ -26,14 +27,14 @@ dist-hook: SMData
cp -r -t "$(distdir)" $(installFiles) cp -r -t "$(distdir)" $(installFiles)
install-exec-hook: install-exec-hook:
mkdir -p "$(prefix)/$(productID)" mkdir -p "$(DESTDIR)$(prefix)/$(productID)"
$(INSTALL) $(installFiles) "$(prefix)/$(productID)" $(INSTALL) $(installFiles) "$(DESTDIR)$(prefix)/$(productID)"
install-data-local: install-data-local:
cp -r -t "$(prefix)/$(productID)" $(installData) mkdir -p "$(DESTDIR)$(prefix)/$(productID)/Songs"
mkdir -p "$(prefix)/$(productID)/Songs" cp -r -t "$(DESTDIR)$(prefix)/$(productID)" $(installData)
uninstall-hook: uninstall-hook:
rm -f "$(prefix)/$(productID)/stepmania" rm -f "$(DESTDIR)$(prefix)/$(productID)/stepmania"
rm -f "$(prefix)/$(productID)/GtkModule.so" rm -f "$(DESTDIR)$(prefix)/$(productID)/GtkModule.so"
# todo: properly remove data # todo: properly remove data
View File
View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File
Executable → Regular
View File
+6 -2
View File
@@ -404,6 +404,9 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
trail.Init(); trail.Init();
// XXX: Why are beginner and challenge excluded here? -Wolfman2000 // 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 ) switch( cd )
{ {
case Difficulty_Beginner: case Difficulty_Beginner:
@@ -412,6 +415,7 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
return false; return false;
default: break; default: break;
} }
*/
// Construct a new Trail, add it to the cache, then return it. // Construct a new Trail, add it to the cache, then return it.
// Different seed for each course, but the same for the whole round: // 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 ) FOREACH_CONST( CourseEntry, m_vEntries, e )
{ {
if( e->iChooseIndex == SongSort_MostPlays && e->iChooseIndex != -1 ) if( e->songSort == SongSort_MostPlays && e->iChooseIndex != -1 )
return true; return true;
if( e->iChooseIndex == SongSort_FewestPlays && e->iChooseIndex != -1 ) if( e->songSort == SongSort_FewestPlays && e->iChooseIndex != -1 )
return true; return true;
} }
+5
View File
@@ -2109,6 +2109,11 @@ Difficulty GameState::GetHardestStepsDifficulty() const
return dc; return dc;
} }
void GameState::SetNewStageSeed()
{
m_iStageSeed= rand();
}
bool GameState::IsEventMode() const bool GameState::IsEventMode() const
{ {
return m_bTemporaryEventMode || PREFSMAN->m_bEventMode; return m_bTemporaryEventMode || PREFSMAN->m_bEventMode;
+2
View File
@@ -117,6 +117,8 @@ public:
int m_iGameSeed, m_iStageSeed; int m_iGameSeed, m_iStageSeed;
RString m_sStageGUID; RString m_sStageGUID;
void SetNewStageSeed();
/** /**
* @brief Determine if a second player can join in at this time. * @brief Determine if a second player can join in at this time.
* @return true if a player can still enter the game, false otherwise. */ * @return true if a player can still enter the game, false otherwise. */
+104 -26
View File
@@ -5,47 +5,47 @@
#include "XmlFile.h" #include "XmlFile.h"
#include "LocalizedString.h" #include "LocalizedString.h"
TapNote TAP_EMPTY ( TapNoteType_Empty, 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_TAP ( TapNoteType_Tap, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 );
TapNote TAP_ORIGINAL_LIFT ( TapNoteType_Lift, 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_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_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_MINE ( TapNoteType_Mine, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 );
TapNote TAP_ORIGINAL_ATTACK ( TapNoteType_Attack, 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_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_FAKE ( TapNoteType_Fake, TapNoteSubType_Invalid, TapNoteSource_Original, "", 0, -1 );
//TapNote TAP_ORIGINAL_MINE_HEAD ( TapNoteType_HoldHead, TapNoteSubType_Mine, 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_TAP ( TapNoteType_Tap, TapNoteSubType_Invalid, TapNoteSource_Addition, "", 0, -1 );
TapNote TAP_ADDITION_MINE ( TapNoteType_Mine, TapNoteSubType_Invalid, TapNoteSource_Addition, "", 0, -1 ); TapNote TAP_ADDITION_MINE ( TapNoteType_Mine, TapNoteSubType_Invalid, TapNoteSource_Addition, "", 0, -1 );
static const char *TapNoteTypeNames[] = { static const char *TapNoteTypeNames[] = {
"Empty", "Empty",
"Tap", "Tap",
"HoldHead", "HoldHead",
"HoldTail", "HoldTail",
"Mine", "Mine",
"Lift", "Lift",
"Attack", "Attack",
"AutoKeySound", "AutoKeySound",
"Fake", "Fake",
}; };
XToString( TapNoteType ); XToString( TapNoteType );
XToLocalizedString( TapNoteType ); XToLocalizedString( TapNoteType );
LuaXType( TapNoteType ); LuaXType( TapNoteType );
static const char *TapNoteSubTypeNames[] = { static const char *TapNoteSubTypeNames[] = {
"Hold", "Hold",
"Roll", "Roll",
//"Mine", //"Mine",
}; };
XToString( TapNoteSubType ); XToString( TapNoteSubType );
XToLocalizedString( TapNoteSubType ); XToLocalizedString( TapNoteSubType );
LuaXType( TapNoteSubType ); LuaXType( TapNoteSubType );
static const char *TapNoteSourceNames[] = { static const char *TapNoteSourceNames[] = {
"Original", "Original",
"Addition", "Addition",
}; };
XToString( TapNoteSource ); XToString( TapNoteSource );
XToLocalizedString( TapNoteSource ); XToLocalizedString( TapNoteSource );
@@ -127,7 +127,7 @@ static const int ROWS_PER_MEASURE = ROWS_PER_BEAT * BEATS_PER_MEASURE;
* @return the quantized NoteType. */ * @return the quantized NoteType. */
NoteType GetNoteType( int row ) 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/8) == 0) return NOTE_TYPE_8TH;
else if( row % (ROWS_PER_MEASURE/12) == 0) return NOTE_TYPE_12TH; else if( row % (ROWS_PER_MEASURE/12) == 0) return NOTE_TYPE_12TH;
else if( row % (ROWS_PER_MEASURE/16) == 0) return NOTE_TYPE_16TH; else if( row % (ROWS_PER_MEASURE/16) == 0) return NOTE_TYPE_16TH;
@@ -200,6 +200,84 @@ float HoldNoteResult::GetLastHeldBeat() const
return NoteRowToBeat(iLastHeldRow); return NoteRowToBeat(iLastHeldRow);
} }
// lua start
#include "LuaBinding.h"
/** @brief Allow Lua to have access to the TapNoteResult. */
class LunaTapNoteResult: public Luna<TapNoteResult>
{
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<HoldNoteResult>
{
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<TapNote>
{
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 * (c) 2001-2004 Chris Danford, Glenn Maynard
* All rights reserved. * All rights reserved.
+23 -14
View File
@@ -31,6 +31,9 @@ struct TapNoteResult
// XML // XML
XNode* CreateNode() const; XNode* CreateNode() const;
void LoadFromNode( const XNode* pNode ); void LoadFromNode( const XNode* pNode );
// Lua
void PushSelf( lua_State *L );
}; };
/** @brief The result of holding (or letting go of) a hold note. */ /** @brief The result of holding (or letting go of) a hold note. */
struct HoldNoteResult struct HoldNoteResult
@@ -73,6 +76,9 @@ struct HoldNoteResult
// XML // XML
XNode* CreateNode() const; XNode* CreateNode() const;
void LoadFromNode( const XNode* pNode ); void LoadFromNode( const XNode* pNode );
// Lua
void PushSelf( lua_State *L );
}; };
/** @brief What is the TapNote's core type? */ /** @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_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_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. */ TapNoteType_Fake, /**< This arrow can't be scored for or against the player. */
NUM_TapNoteType, NUM_TapNoteType,
TapNoteType_Invalid TapNoteType_Invalid
}; };
const RString& TapNoteTypeToString( TapNoteType tnt ); const RString& TapNoteTypeToString( TapNoteType tnt );
const RString& TapNoteTypeToLocalizedString( TapNoteType tnt ); const RString& TapNoteTypeToLocalizedString( TapNoteType tnt );
@@ -97,11 +103,11 @@ LuaDeclareType( TapNoteType );
/** @brief The list of a TapNote's sub types. */ /** @brief The list of a TapNote's sub types. */
enum TapNoteSubType enum TapNoteSubType
{ {
TapNoteSubType_Hold, /**< The start of a traditional hold note. */ TapNoteSubType_Hold, /**< The start of a traditional hold note. */
TapNoteSubType_Roll, /**< The start of a roll note that must be hit repeatedly. */ TapNoteSubType_Roll, /**< The start of a roll note that must be hit repeatedly. */
//TapNoteSubType_Mine, //TapNoteSubType_Mine,
NUM_TapNoteSubType, NUM_TapNoteSubType,
TapNoteSubType_Invalid TapNoteSubType_Invalid
}; };
const RString& TapNoteSubTypeToString( TapNoteSubType tnst ); const RString& TapNoteSubTypeToString( TapNoteSubType tnst );
const RString& TapNoteSubTypeToLocalizedString( TapNoteSubType tnst ); const RString& TapNoteSubTypeToLocalizedString( TapNoteSubType tnst );
@@ -110,10 +116,10 @@ LuaDeclareType( TapNoteSubType );
/** @brief The different places a TapNote could come from. */ /** @brief The different places a TapNote could come from. */
enum TapNoteSource enum TapNoteSource
{ {
TapNoteSource_Original, /**< This note is part of the original NoteData. */ TapNoteSource_Original, /**< This note is part of the original NoteData. */
TapNoteSource_Addition, /**< This note is additional note added by a transform. */ TapNoteSource_Addition, /**< This note is additional note added by a transform. */
NUM_TapNoteSource, NUM_TapNoteSource,
TapNoteSource_Invalid TapNoteSource_Invalid
}; };
const RString& TapNoteSourceToString( TapNoteSource tns ); const RString& TapNoteSourceToString( TapNoteSource tns );
const RString& TapNoteSourceToLocalizedString( TapNoteSource tns ); const RString& TapNoteSourceToLocalizedString( TapNoteSource tns );
@@ -145,11 +151,14 @@ struct TapNote
// also used for hold_head only: // also used for hold_head only:
int iDuration; int iDuration;
HoldNoteResult HoldResult; HoldNoteResult HoldResult;
// XML // XML
XNode* CreateNode() const; XNode* CreateNode() const;
void LoadFromNode( const XNode* pNode ); void LoadFromNode( const XNode* pNode );
// Lua
void PushSelf( lua_State *L );
TapNote(): type(TapNoteType_Empty), subType(TapNoteSubType_Invalid), TapNote(): type(TapNoteType_Empty), subType(TapNoteSubType_Invalid),
source(TapNoteSource_Original), result(), pn(PLAYER_INVALID), source(TapNoteSource_Original), result(), pn(PLAYER_INVALID),
bHopoPossible(false), sAttackModifiers(""), fAttackDurationSeconds(0), 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). * @brief Convert the note row to note row (returns itself).
* @param row the row to convert. * @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. * @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. * @brief Convert the note row to beat.
* @param row the row to convert. * @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). * @brief Convert the beat row to beat (return itself).
+45 -24
View File
@@ -1464,7 +1464,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vector<TrackRowTap
{ {
//LOG->Trace("tap note scoring time."); //LOG->Trace("tap note scoring time.");
TapNote &tn = *vTN[0].pTN; TapNote &tn = *vTN[0].pTN;
SetHoldJudgment( tn.result.tns, tn.HoldResult.hns, iFirstTrackWithMaxEndRow ); SetHoldJudgment( tn, iFirstTrackWithMaxEndRow );
HandleHoldScore( tn ); HandleHoldScore( tn );
//LOG->Trace("hold result = %s",StringConversion::ToString(tn.HoldResult.hns).c_str()); //LOG->Trace("hold result = %s",StringConversion::ToString(tn.HoldResult.hns).c_str());
} }
@@ -1914,7 +1914,6 @@ void Player::DoTapScoreNone()
SendComboMessages( iOldCombo, iOldMissCombo ); SendComboMessages( iOldCombo, iOldMissCombo );
if( m_pLifeMeter ) if( m_pLifeMeter )
m_pLifeMeter->HandleTapScoreNone(); m_pLifeMeter->HandleTapScoreNone();
// TODO: Remove use of PlayerNumber // TODO: Remove use of PlayerNumber
@@ -1924,7 +1923,7 @@ void Player::DoTapScoreNone()
if( PENALIZE_TAP_SCORE_NONE ) 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. // the ScoreKeeper will subtract points later.
} }
} }
@@ -1960,7 +1959,7 @@ void Player::ScoreAllActiveHoldsLetGo()
tn.HoldResult.hns = HNS_LetGo; tn.HoldResult.hns = HNS_LetGo;
tn.HoldResult.fLife = 0; tn.HoldResult.fLife = 0;
SetHoldJudgment( tn.result.tns, tn.HoldResult.hns, iTrack ); SetHoldJudgment( tn, iTrack );
HandleHoldScore( tn ); HandleHoldScore( tn );
} }
} }
@@ -2796,22 +2795,12 @@ void Player::UpdateJudgedRows()
if (tn.type == TapNoteType_Empty || if (tn.type == TapNoteType_Empty ||
tn.type == TapNoteType_Mine || tn.type == TapNoteType_Mine ||
tn.type == TapNoteType_AutoKeysound) continue; tn.type == TapNoteType_AutoKeysound) continue;
SetJudgment( tn.result.tns, iTrack, tn.result.fTapNoteOffset ); SetJudgment( iRow, iTrack, tn );
} }
} }
else else
{ {
vector<int> viColsWithTaps; SetJudgment( iRow, m_NoteData.GetFirstTrackWithTapOrHoldHead(iRow), NoteDataWithScoring::LastTapNoteWithResult( m_NoteData, iRow ) );
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 );
} }
HandleTapRowScore( iRow ); HandleTapRowScore( iRow );
} }
@@ -3245,7 +3234,7 @@ void Player::HandleHoldCheckpoint(int iRow,
ChangeLife( iNumHoldsMissedThisRow == 0? TNS_CheckpointHit:TNS_CheckpointMiss ); 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 ) void Player::HandleHoldScore( const TapNote &tn )
@@ -3330,7 +3319,7 @@ void Player::SetMineJudgment( TapNoteScore tns , int iTrack )
} }
} }
void Player::SetJudgment( TapNoteScore tns, int iTrack, float fTapNoteOffset, vector<int> viCols ) void Player::SetJudgment( int iRow, int iTrack, const TapNote &tn, TapNoteScore tns, float fTapNoteOffset )
{ {
if( m_bSendJudgmentAndComboMessages ) if( m_bSendJudgmentAndComboMessages )
{ {
@@ -3340,17 +3329,44 @@ void Player::SetJudgment( TapNoteScore tns, int iTrack, float fTapNoteOffset, ve
msg.SetParam( "FirstTrack", iTrack ); msg.SetParam( "FirstTrack", iTrack );
msg.SetParam( "TapNoteScore", tns ); msg.SetParam( "TapNoteScore", tns );
msg.SetParam( "Early", fTapNoteOffset < 0.0f ); msg.SetParam( "Early", fTapNoteOffset < 0.0f );
msg.SetParam( "TapNoteOffset", fTapNoteOffset ); msg.SetParam( "TapNoteOffset", tn.result.fTapNoteOffset );
msg.SetParam( "Tracks" , viCols );
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 ); 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() ); ASSERT( iTrack < (int)m_vpHoldJudgment.size() );
if( m_vpHoldJudgment[iTrack] ) if( m_vpHoldJudgment[iTrack] )
m_vpHoldJudgment[iTrack]->SetHoldJudgment( hns ); m_vpHoldJudgment[iTrack]->SetHoldJudgment( tn.HoldResult.hns );
if( m_bSendJudgmentAndComboMessages ) if( m_bSendJudgmentAndComboMessages )
{ {
@@ -3359,8 +3375,13 @@ void Player::SetHoldJudgment( TapNoteScore tns, HoldNoteScore hns, int iTrack )
msg.SetParam( "MultiPlayer", m_pPlayerState->m_mp ); msg.SetParam( "MultiPlayer", m_pPlayerState->m_mp );
msg.SetParam( "FirstTrack", iTrack ); msg.SetParam( "FirstTrack", iTrack );
msg.SetParam( "NumTracks", (int)m_vpHoldJudgment.size() ); msg.SetParam( "NumTracks", (int)m_vpHoldJudgment.size() );
msg.SetParam( "TapNoteScore", tns ); msg.SetParam( "TapNoteScore", tn.result.tns );
msg.SetParam( "HoldNoteScore", hns ); msg.SetParam( "HoldNoteScore", tn.HoldResult.hns );
Lua* L = LUA->Get();
tn.PushSelf(L);
msg.SetParamFromStack( L, "TapNote" );
MESSAGEMAN->Broadcast( msg ); MESSAGEMAN->Broadcast( msg );
} }
} }
+3 -3
View File
@@ -132,9 +132,9 @@ protected:
void PlayKeysound( const TapNote &tn, TapNoteScore score ); void PlayKeysound( const TapNote &tn, TapNoteScore score );
void SetMineJudgment( TapNoteScore tns , int iTrack ); void SetMineJudgment( TapNoteScore tns , int iTrack );
void SetJudgment( TapNoteScore tns, int iFirstTrack, float fTapNoteOffset ) { vector<int> viCols (1,iFirstTrack); SetJudgment( tns, iFirstTrack, fTapNoteOffset, viCols ); } void SetJudgment( int iRow, int iFirstTrack, const TapNote &tn ) { SetJudgment( iRow, iFirstTrack, tn, tn.result.tns, tn.result.fTapNoteOffset ); }
void SetJudgment( TapNoteScore tns, int iFirstTrack, float fTapNoteOffset, vector<int> viCols ); // -1 if no track as in TNS_Miss void SetJudgment( int iRow, int iFirstTrack, const TapNote &tn, TapNoteScore tns, float fTapNoteOffset ); // -1 if no track as in TNS_Miss
void SetHoldJudgment( TapNoteScore tns, HoldNoteScore hns, int iTrack ); void SetHoldJudgment( TapNote &tn, int iTrack );
void SetCombo( int iCombo, int iMisses ); void SetCombo( int iCombo, int iMisses );
void ChangeLife( TapNoteScore tns ); void ChangeLife( TapNoteScore tns );
+66
View File
@@ -2618,6 +2618,72 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
pi->m_pLifeMeter->OnSongEnded(); 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<StepsType> trail_sts;
vector<CourseDifficulty> 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; GAMESTATE->m_bLoadingNextSong = true;
MESSAGEMAN->Broadcast( "BeforeLoadingNextCourseSong" ); MESSAGEMAN->Broadcast( "BeforeLoadingNextCourseSong" );
m_NextSong.Reset(); m_NextSong.Reset();