diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml
index 964eb04199..b10019410c 100644
--- a/Docs/Luadoc/Lua.xml
+++ b/Docs/Luadoc/Lua.xml
@@ -780,6 +780,7 @@
+
@@ -1453,6 +1454,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1777,6 +1792,12 @@
+
+
+
+
+
+
@@ -1832,6 +1853,11 @@
+
+
+
+
+
@@ -1951,6 +1977,11 @@
+
+
+
+
+
diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml
index 1adcb4b5c3..589d6da91b 100644
--- a/Docs/Luadoc/LuaDocumentation.xml
+++ b/Docs/Luadoc/LuaDocumentation.xml
@@ -2335,6 +2335,9 @@ save yourself some time, copy this for undocumented things:
Returns the song options as a string.
+
+ Returns the song options for the specified ModsLevel as an object.
+
Returns how much of the song is through at beat fBeat.
@@ -2830,7 +2833,7 @@ save yourself some time, copy this for undocumented things:
- Most options fall into one of two types: float or bool.
+ Most options fall into one of four types: float, int, bool, or enum.
Float type options have this interface:
Option(value, approach_speed)
If value is a float, sets the TimeSpacing modifier to value.
@@ -2843,7 +2846,9 @@ save yourself some time, copy this for undocumented things:
a,b= options:Boost(5) -- Sets a and b to the previous values, NOT to 5 and .5. Sets the value to 5 and leaves the approach speed at whatever it was.
Setting the approach speed only matters when modifying the PlayerOptions from ModsLevel_Song.
+ Int type options are similar to float in that they return and take a number, but they do not have an approach speed.
Bool type options have an almost identical interface, the difference is that they can not have an approach speed.
+ Enum type options are almost identical to bool type. They take and return an enum value.
For brevity, the functions are only given a description if the option requires careful handling or does not follow the float or bool interfaces.
@@ -4044,6 +4049,36 @@ save yourself some time, copy this for undocumented things:
Returns true if the specified song was loaded from AdditionalSongs.
+
+
+ See the description for PlayerOptions. The functions follow the same design.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Limited to the range 0 < rate <= 3 because speeds greater than 3 are likely to crash.
+
+
+
+
Returns the current beats per second.
diff --git a/src/AdjustSync.cpp b/src/AdjustSync.cpp
index fb88d39475..0234cffbf4 100644
--- a/src/AdjustSync.cpp
+++ b/src/AdjustSync.cpp
@@ -141,25 +141,22 @@ void AdjustSync::RevertSyncChanges()
static LocalizedString AUTOSYNC_CORRECTION_APPLIED ( "AdjustSync", "Autosync: Correction applied." );
static LocalizedString AUTOSYNC_CORRECTION_NOT_APPLIED ( "AdjustSync", "Autosync: Correction NOT applied. Deviation too high." );
-static LocalizedString AUTOSYNC_SONG ( "AdjustSync", "Autosync Song" );
-static LocalizedString AUTOSYNC_MACHINE ( "AdjustSync", "Autosync Machine" );
-static LocalizedString AUTOSYNC_TEMPO ( "AdjustSync", "Autosync Tempo" );
void AdjustSync::HandleAutosync( float fNoteOffBySeconds, float fStepTime )
{
if( GAMESTATE->IsCourseMode() )
return;
- SongOptions::AutosyncType type = GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType;
+ AutosyncType type = GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType;
switch( type ) {
- case SongOptions::AUTOSYNC_OFF:
+ case AutosyncType_Off:
return;
- case SongOptions::AUTOSYNC_TEMPO:
+ case AutosyncType_Tempo:
{
// We collect all of the data and process it at the end
s_vAutosyncTempoData.push_back( make_pair(fStepTime, fNoteOffBySeconds) );
break;
}
- case SongOptions::AUTOSYNC_MACHINE:
- case SongOptions::AUTOSYNC_SONG:
+ case AutosyncType_Machine:
+ case AutosyncType_Song:
{
s_fAutosyncOffset[s_iAutosyncOffsetSample] = fNoteOffBySeconds;
++s_iAutosyncOffsetSample;
@@ -179,7 +176,7 @@ void AdjustSync::HandleSongEnd()
{
if( GAMESTATE->IsCourseMode() )
return;
- if( GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType == SongOptions::AUTOSYNC_TEMPO )
+ if( GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType == AutosyncType_Tempo )
{
AutosyncTempo();
}
@@ -192,25 +189,13 @@ void AdjustSync::AutosyncOffset()
const float mean = calc_mean( s_fAutosyncOffset, s_fAutosyncOffset+OFFSET_SAMPLE_COUNT );
const float stddev = calc_stddev( s_fAutosyncOffset, s_fAutosyncOffset+OFFSET_SAMPLE_COUNT );
- RString sAutosyncType;
- SongOptions::AutosyncType type = GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType;
- switch( type )
- {
- case SongOptions::AUTOSYNC_SONG:
- sAutosyncType = AUTOSYNC_SONG;
- break;
- case SongOptions::AUTOSYNC_MACHINE:
- sAutosyncType = AUTOSYNC_MACHINE;
- break;
- default:
- FAIL_M(ssprintf("Invalid autosync type: %i", type));
- }
+ AutosyncType type = GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType;
if( stddev < .03f ) // If they stepped with less than .03 error
{
switch( type )
{
- case SongOptions::AUTOSYNC_SONG:
+ case AutosyncType_Song:
{
GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += mean;
const vector& vpSteps = GAMESTATE->m_pCurSong->GetAllSteps();
@@ -224,7 +209,7 @@ void AdjustSync::AutosyncOffset()
}
break;
}
- case SongOptions::AUTOSYNC_MACHINE:
+ case AutosyncType_Machine:
// Step timing is not needed for this operation.
PREFSMAN->m_fGlobalOffsetSeconds.Set( PREFSMAN->m_fGlobalOffsetSeconds + mean );
break;
diff --git a/src/GameCommand.cpp b/src/GameCommand.cpp
index e3b60582d2..cf399ad2ef 100644
--- a/src/GameCommand.cpp
+++ b/src/GameCommand.cpp
@@ -805,9 +805,9 @@ void GameCommand::ApplySelf( const vector &vpns ) const
// we don't override the user's changes if they back out.
if( GAMESTATE->m_PlayMode == PLAY_MODE_ONI &&
GAMESTATE->m_PlayMode != OldPlayMode &&
- GAMESTATE->m_SongOptions.GetStage().m_LifeType == SongOptions::LIFE_BAR )
+ GAMESTATE->m_SongOptions.GetStage().m_LifeType == LifeType_Bar )
{
- SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_LifeType, SongOptions::LIFE_BATTERY );
+ SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_LifeType, LifeType_Battery );
}
}
diff --git a/src/GameState.cpp b/src/GameState.cpp
index 12554cb666..fd135343d8 100644
--- a/src/GameState.cpp
+++ b/src/GameState.cpp
@@ -2366,6 +2366,12 @@ public:
LuaHelpers::Push( L, s );
return 1;
}
+ static int GetSongOptionsObject( T* p, lua_State *L )
+ {
+ ModsLevel m = Enum::Check( L, 1 );
+ p->m_SongOptions.Get(m).PushSelf(L);
+ return 1;
+ }
static int GetDefaultSongOptions( T* p, lua_State *L )
{
SongOptions so;
@@ -2643,6 +2649,7 @@ public:
ADD_METHOD( GetPremium );
ADD_METHOD( GetSongOptionsString );
ADD_METHOD( GetSongOptions );
+ ADD_METHOD( GetSongOptionsObject );
ADD_METHOD( GetDefaultSongOptions );
ADD_METHOD( ApplyPreferredModifiers );
ADD_METHOD( ApplyStageModifiers );
diff --git a/src/LifeMeter.cpp b/src/LifeMeter.cpp
index 1d6fd285fb..2f72d0c953 100644
--- a/src/LifeMeter.cpp
+++ b/src/LifeMeter.cpp
@@ -4,13 +4,13 @@
#include "LifeMeterBattery.h"
#include "LifeMeterTime.h"
-LifeMeter *LifeMeter::MakeLifeMeter( SongOptions::LifeType t )
+LifeMeter *LifeMeter::MakeLifeMeter( LifeType t )
{
switch( t )
{
- case SongOptions::LIFE_BAR: return new LifeMeterBar;
- case SongOptions::LIFE_BATTERY: return new LifeMeterBattery;
- case SongOptions::LIFE_TIME: return new LifeMeterTime;
+ case LifeType_Bar: return new LifeMeterBar;
+ case LifeType_Battery: return new LifeMeterBattery;
+ case LifeType_Time: return new LifeMeterTime;
default:
FAIL_M(ssprintf("Unrecognized LifeMeter type: %i", t));
}
diff --git a/src/LifeMeter.h b/src/LifeMeter.h
index 33a74be67f..1f45c68bea 100644
--- a/src/LifeMeter.h
+++ b/src/LifeMeter.h
@@ -41,7 +41,7 @@ public:
virtual float GetLife() const { return 0; } // for cosmetic use only
virtual void UpdateNonstopLifebar() { }
- static LifeMeter *MakeLifeMeter( SongOptions::LifeType t );
+ static LifeMeter *MakeLifeMeter( LifeType t );
//
// Lua
diff --git a/src/LifeMeterBar.cpp b/src/LifeMeterBar.cpp
index 90a9106228..09f56eea70 100644
--- a/src/LifeMeterBar.cpp
+++ b/src/LifeMeterBar.cpp
@@ -31,16 +31,16 @@ LifeMeterBar::LifeMeterBar()
m_pPlayerState = NULL;
- SongOptions::DrainType dtype = GAMESTATE->m_SongOptions.GetStage().m_DrainType;
+ DrainType dtype = GAMESTATE->m_SongOptions.GetStage().m_DrainType;
switch( dtype )
{
- case SongOptions::DRAIN_NORMAL:
+ case DrainType_Normal:
m_fLifePercentage = INITIAL_VALUE;
break;
/* These types only go down, so they always start at full. */
- case SongOptions::DRAIN_NO_RECOVER:
- case SongOptions::DRAIN_SUDDEN_DEATH:
+ case DrainType_NoRecover:
+ case DrainType_SuddenDeath:
m_fLifePercentage = 1.0f; break;
default:
FAIL_M(ssprintf("Invalid DrainType: %i", dtype));
@@ -132,12 +132,12 @@ void LifeMeterBar::ChangeLife( TapNoteScore score )
switch( GAMESTATE->m_SongOptions.GetSong().m_DrainType )
{
DEFAULT_FAIL( GAMESTATE->m_SongOptions.GetSong().m_DrainType );
- case SongOptions::DRAIN_NORMAL:
+ case DrainType_Normal:
break;
- case SongOptions::DRAIN_NO_RECOVER:
+ case DrainType_NoRecover:
fDeltaLife = min( fDeltaLife, 0 );
break;
- case SongOptions::DRAIN_SUDDEN_DEATH:
+ case DrainType_SuddenDeath:
if( score < MIN_STAY_ALIVE )
fDeltaLife = -1.0f;
else
@@ -151,10 +151,10 @@ void LifeMeterBar::ChangeLife( TapNoteScore score )
void LifeMeterBar::ChangeLife( HoldNoteScore score, TapNoteScore tscore )
{
float fDeltaLife=0.f;
- SongOptions::DrainType dtype = GAMESTATE->m_SongOptions.GetSong().m_DrainType;
+ DrainType dtype = GAMESTATE->m_SongOptions.GetSong().m_DrainType;
switch( dtype )
{
- case SongOptions::DRAIN_NORMAL:
+ case DrainType_Normal:
switch( score )
{
case HNS_Held: fDeltaLife = m_fLifePercentChange.GetValue(SE_Held); break;
@@ -166,7 +166,7 @@ void LifeMeterBar::ChangeLife( HoldNoteScore score, TapNoteScore tscore )
if( IsHot() && score == HNS_LetGo )
fDeltaLife = -0.10f; // make it take a while to get back to "hot"
break;
- case SongOptions::DRAIN_NO_RECOVER:
+ case DrainType_NoRecover:
switch( score )
{
case HNS_Held: fDeltaLife = +0.000f; break;
@@ -176,7 +176,7 @@ void LifeMeterBar::ChangeLife( HoldNoteScore score, TapNoteScore tscore )
FAIL_M(ssprintf("Invalid HoldNoteScore: %i", score));
}
break;
- case SongOptions::DRAIN_SUDDEN_DEATH:
+ case DrainType_SuddenDeath:
switch( score )
{
case HNS_Held: fDeltaLife = +0; break;
@@ -221,14 +221,14 @@ void LifeMeterBar::ChangeLife( float fDeltaLife )
switch( GAMESTATE->m_SongOptions.GetSong().m_DrainType )
{
- case SongOptions::DRAIN_NORMAL:
- case SongOptions::DRAIN_NO_RECOVER:
+ case DrainType_Normal:
+ case DrainType_NoRecover:
if( fDeltaLife > 0 )
fDeltaLife *= m_fLifeDifficulty;
else
fDeltaLife /= m_fLifeDifficulty;
break;
- case SongOptions::DRAIN_SUDDEN_DEATH:
+ case DrainType_SuddenDeath:
// This should always -1.0f;
if( fDeltaLife < 0 )
fDeltaLife = -1.0f;
diff --git a/src/LuaBinding.cpp b/src/LuaBinding.cpp
index a264675164..0c7aa4dc21 100644
--- a/src/LuaBinding.cpp
+++ b/src/LuaBinding.cpp
@@ -376,6 +376,25 @@ LuaClass::~LuaClass()
LUA->Release( L );
}
+void DefaultNilArgs(lua_State* L, int n)
+{
+ while(lua_gettop(L) < n)
+ {
+ lua_pushnil(L);
+ }
+}
+
+float FArgGTEZero(lua_State* L, int index)
+{
+ float s= FArg(index);
+ if(s < 0)
+ {
+ luaL_error(L, "Arg must be greater than or equal to zero.");
+ }
+ return s;
+}
+
+
/*
* (c) 2005 Glenn Maynard
* All rights reserved.
diff --git a/src/LuaBinding.h b/src/LuaBinding.h
index 91c0392646..91c27c6dec 100644
--- a/src/LuaBinding.h
+++ b/src/LuaBinding.h
@@ -170,6 +170,11 @@ public:
#define LIST_METHOD( method_name ) \
{ #method_name, method_name }
+// Explicitly separates the stack into args and return values.
+// This way, the stack can safely be used to store the previous values.
+void DefaultNilArgs(lua_State* L, int n);
+float FArgGTEZero(lua_State* L, int index);
+
#endif
/*
diff --git a/src/OptionsBinding.h b/src/OptionsBinding.h
new file mode 100644
index 0000000000..67628b541b
--- /dev/null
+++ b/src/OptionsBinding.h
@@ -0,0 +1,95 @@
+/* OptionsBinding - little helpers so that SongOptions and PlayerOptions can more easily have similar interfaces. */
+
+// No .cpp file because it's just some #defines, and not in a makefile because it doesn't need to be.
+// DefaultNilArgs would be in here, but then there would need to be a .cpp file, and DefaultNilArgs is more widely useful.
+
+#ifndef OptionsBinding_H
+#define OptionsBinding_H
+ // Functions are designed to combine Get and Set into one, to be less clumsy to use. -Kyz
+ // If a valid arg is passed, the value is set.
+ // The previous value is returned.
+#define FLOAT_INTERFACE(func_name, member, valid) \
+ static int func_name(T* p, lua_State* L) \
+ { \
+ DefaultNilArgs(L, 2); \
+ lua_pushnumber(L, p->m_f ## member); \
+ lua_pushnumber(L, p->m_Speedf ## member); \
+ if(lua_isnumber(L, 1)) \
+ { \
+ float v= FArg(1); \
+ if(!valid) \
+ { \
+ luaL_error(L, "Invalid value %f", v); \
+ } \
+ p->m_f ## member = v; \
+ if(p->m_Speedf ## member <= 0.0f) \
+ { \
+ p->m_Speedf ## member = 1.0f; \
+ } \
+ } \
+ if(lua_isnumber(L, 2)) \
+ { \
+ p->m_Speedf ## member = FArgGTEZero(L, 2); \
+ } \
+ return 2; \
+ }
+#define INT_INTERFACE(func_name, member) \
+ static int func_name(T* p, lua_State* L) \
+ { \
+ DefaultNilArgs(L, 1); \
+ lua_pushnumber(L, p->m_i ## member); \
+ if(lua_isnumber(L, 1)) \
+ { \
+ p->m_i ## member = IArg(1); \
+ } \
+ return 1; \
+ }
+#define BOOL_INTERFACE(func_name, member) \
+ static int func_name(T* p, lua_State* L) \
+ { \
+ DefaultNilArgs(L, 1); \
+ lua_pushboolean(L, p->m_b ## member); \
+ if(lua_isboolean(L, 1)) \
+ { \
+ p->m_b ## member = BArg(1); \
+ } \
+ return 1; \
+ }
+#define ENUM_INTERFACE(func_name, member, enum_name) \
+ static int func_name(T* p, lua_State* L) \
+ { \
+ DefaultNilArgs(L, 1); \
+ Enum::Push(L, p->m_ ## member); \
+ if(!lua_isnil(L, 1)) \
+ { \
+ p->m_ ## member= Enum::Check(L, 1); \
+ } \
+ return 1; \
+ }
+
+#endif
+
+/*
+ * (c) 2014 Eric Reese
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons to
+ * whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
diff --git a/src/Player.cpp b/src/Player.cpp
index 250446001a..f9abacbcd5 100644
--- a/src/Player.cpp
+++ b/src/Player.cpp
@@ -629,7 +629,7 @@ void Player::Load()
// TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
- bool bOniDead = GAMESTATE->m_SongOptions.GetStage().m_LifeType == SongOptions::LIFE_BATTERY &&
+ bool bOniDead = GAMESTATE->m_SongOptions.GetStage().m_LifeType == LifeType_Battery &&
(m_pPlayerStageStats == NULL || m_pPlayerStageStats->m_bFailed);
/* The editor reuses Players ... so we really need to make sure everything
@@ -1782,7 +1782,7 @@ int Player::GetClosestNonEmptyRow( int iNoteRow, int iMaxRowsAhead, int iMaxRows
bool Player::IsOniDead() const
{
// If we're playing on oni and we've died, do nothing.
- return GAMESTATE->m_SongOptions.GetCurrent().m_LifeType == SongOptions::LIFE_BATTERY && m_pPlayerStageStats && m_pPlayerStageStats->m_bFailed;
+ return GAMESTATE->m_SongOptions.GetCurrent().m_LifeType == LifeType_Battery && m_pPlayerStageStats && m_pPlayerStageStats->m_bFailed;
}
void Player::Fret( int col, int row, const RageTimer &tm, bool bHeld, bool bRelease )
diff --git a/src/PlayerOptions.cpp b/src/PlayerOptions.cpp
index b5eeadb339..cc354c3b95 100644
--- a/src/PlayerOptions.cpp
+++ b/src/PlayerOptions.cpp
@@ -908,6 +908,7 @@ void PlayerOptions::ResetPrefs( ResetPrefsType type )
// lua start
#include "LuaBinding.h"
+#include "OptionsBinding.h"
/** @brief Allow Lua to have access to PlayerOptions. */
class LunaPlayerOptions: public Luna
@@ -930,107 +931,53 @@ public:
return 1;
}
- static float CheckedApproachSpeed(lua_State* L, float s)
- {
- if(s < 0)
- {
- luaL_error(L, "Approach speed must be greater than or equal to zero.");
- }
- return s;
- }
-
- // Explicitly separates the stack into args and return values.
- // This way, the stack can safely be used to store the previous values.
- static void DefaultNilArgs(lua_State* L, int n)
- {
- while(lua_gettop(L) < n)
- {
- lua_pushnil(L);
- }
- }
-
- // Functions are designed to combine Get and Set into one, to be less clumsy to use. -Kyz
- // If a valid arg is passed, the value is set.
- // The previous value is returned.
-#define FLOAT_INTERFACE(func_name, member) \
- static int func_name(T* p, lua_State* L) \
- { \
- DefaultNilArgs(L, 2); \
- lua_pushnumber(L, p->m_f ## member); \
- lua_pushnumber(L, p->m_Speedf ## member); \
- if(lua_isnumber(L, 1)) \
- { \
- p->m_f ## member = FArg(1); \
- if(p->m_Speedf ## member <= 0.0f) \
- { \
- p->m_Speedf ## member = 1.0f; \
- } \
- } \
- if(lua_isnumber(L, 2)) \
- { \
- p->m_Speedf ## member = CheckedApproachSpeed(L, FArg(2)); \
- } \
- return 2; \
- }
-#define BOOL_INTERFACE(func_name, member) \
- static int func_name(T* p, lua_State* L) \
- { \
- DefaultNilArgs(L, 1); \
- lua_pushboolean(L, p->m_b ## member); \
- if(lua_isboolean(L, 1)) \
- { \
- p->m_b ## member = BArg(1); \
- } \
- return 1; \
- }
-
// Direct control functions, for themes that can handle it.
- FLOAT_INTERFACE(TimeSpacing, TimeSpacing);
- FLOAT_INTERFACE(MaxScrollBPM, MaxScrollBPM);
- FLOAT_INTERFACE(ScrollSpeed, ScrollSpeed);
- FLOAT_INTERFACE(ScrollBPM, ScrollBPM);
- FLOAT_INTERFACE(Boost, Accels[PlayerOptions::ACCEL_BOOST]);
- FLOAT_INTERFACE(Brake, Accels[PlayerOptions::ACCEL_BRAKE]);
- FLOAT_INTERFACE(Wave, Accels[PlayerOptions::ACCEL_WAVE]);
- FLOAT_INTERFACE(Expand, Accels[PlayerOptions::ACCEL_EXPAND]);
- FLOAT_INTERFACE(Boomerang, Accels[PlayerOptions::ACCEL_BOOMERANG]);
- FLOAT_INTERFACE(Drunk, Effects[PlayerOptions::EFFECT_DRUNK]);
- FLOAT_INTERFACE(Dizzy, Effects[PlayerOptions::EFFECT_DIZZY]);
- FLOAT_INTERFACE(Confusion, Effects[PlayerOptions::EFFECT_CONFUSION]);
- FLOAT_INTERFACE(Mini, Effects[PlayerOptions::EFFECT_MINI]);
- FLOAT_INTERFACE(Tiny, Effects[PlayerOptions::EFFECT_TINY]);
- FLOAT_INTERFACE(Flip, Effects[PlayerOptions::EFFECT_FLIP]);
- FLOAT_INTERFACE(Invert, Effects[PlayerOptions::EFFECT_INVERT]);
- FLOAT_INTERFACE(Tornado, Effects[PlayerOptions::EFFECT_TORNADO]);
- FLOAT_INTERFACE(Tipsy, Effects[PlayerOptions::EFFECT_TIPSY]);
- FLOAT_INTERFACE(Bumpy, Effects[PlayerOptions::EFFECT_BUMPY]);
- FLOAT_INTERFACE(Beat, Effects[PlayerOptions::EFFECT_BEAT]);
- FLOAT_INTERFACE(Xmode, Effects[PlayerOptions::EFFECT_XMODE]);
- FLOAT_INTERFACE(Twirl, Effects[PlayerOptions::EFFECT_TWIRL]);
- FLOAT_INTERFACE(Roll, Effects[PlayerOptions::EFFECT_ROLL]);
- FLOAT_INTERFACE(Hidden, Appearances[PlayerOptions::APPEARANCE_HIDDEN]);
- FLOAT_INTERFACE(HiddenOffset, Appearances[PlayerOptions::APPEARANCE_HIDDEN_OFFSET]);
- FLOAT_INTERFACE(Sudden, Appearances[PlayerOptions::APPEARANCE_SUDDEN]);
- FLOAT_INTERFACE(SuddenOffset, Appearances[PlayerOptions::APPEARANCE_SUDDEN_OFFSET]);
- FLOAT_INTERFACE(Stealth, Appearances[PlayerOptions::APPEARANCE_STEALTH]);
- FLOAT_INTERFACE(Blink, Appearances[PlayerOptions::APPEARANCE_BLINK]);
- FLOAT_INTERFACE(RandomVanish, Appearances[PlayerOptions::APPEARANCE_RANDOMVANISH]);
- FLOAT_INTERFACE(Reverse, Scrolls[PlayerOptions::SCROLL_REVERSE]);
- FLOAT_INTERFACE(Split, Scrolls[PlayerOptions::SCROLL_SPLIT]);
- FLOAT_INTERFACE(Alternate, Scrolls[PlayerOptions::SCROLL_ALTERNATE]);
- FLOAT_INTERFACE(Cross, Scrolls[PlayerOptions::SCROLL_CROSS]);
- FLOAT_INTERFACE(Centered, Scrolls[PlayerOptions::SCROLL_CENTERED]);
- FLOAT_INTERFACE(Dark, Dark);
- FLOAT_INTERFACE(Blind, Blind);
- FLOAT_INTERFACE(Cover, Cover);
- FLOAT_INTERFACE(RandAttack, RandAttack);
- FLOAT_INTERFACE(NoAttack, NoAttack);
- FLOAT_INTERFACE(PlayerAutoPlay, PlayerAutoPlay);
- FLOAT_INTERFACE(Skew, Skew);
- FLOAT_INTERFACE(Tilt, PerspectiveTilt);
- FLOAT_INTERFACE(Passmark, Passmark); // Passmark is not sanity checked to the [0, 1] range because LifeMeterBar::IsFailing is the only thing that uses it, and it's used in a <= test. Any theme passing a value outside the [0, 1] range probably expects the result they get. -Kyz
- FLOAT_INTERFACE(RandomSpeed, RandomSpeed);
+ FLOAT_INTERFACE(TimeSpacing, TimeSpacing, true);
+ FLOAT_INTERFACE(MaxScrollBPM, MaxScrollBPM, true);
+ FLOAT_INTERFACE(ScrollSpeed, ScrollSpeed, true);
+ FLOAT_INTERFACE(ScrollBPM, ScrollBPM, true);
+ FLOAT_INTERFACE(Boost, Accels[PlayerOptions::ACCEL_BOOST], true);
+ FLOAT_INTERFACE(Brake, Accels[PlayerOptions::ACCEL_BRAKE], true);
+ FLOAT_INTERFACE(Wave, Accels[PlayerOptions::ACCEL_WAVE], true);
+ FLOAT_INTERFACE(Expand, Accels[PlayerOptions::ACCEL_EXPAND], true);
+ FLOAT_INTERFACE(Boomerang, Accels[PlayerOptions::ACCEL_BOOMERANG], true);
+ FLOAT_INTERFACE(Drunk, Effects[PlayerOptions::EFFECT_DRUNK], true);
+ FLOAT_INTERFACE(Dizzy, Effects[PlayerOptions::EFFECT_DIZZY], true);
+ FLOAT_INTERFACE(Confusion, Effects[PlayerOptions::EFFECT_CONFUSION], true);
+ FLOAT_INTERFACE(Mini, Effects[PlayerOptions::EFFECT_MINI], true);
+ FLOAT_INTERFACE(Tiny, Effects[PlayerOptions::EFFECT_TINY], true);
+ FLOAT_INTERFACE(Flip, Effects[PlayerOptions::EFFECT_FLIP], true);
+ FLOAT_INTERFACE(Invert, Effects[PlayerOptions::EFFECT_INVERT], true);
+ FLOAT_INTERFACE(Tornado, Effects[PlayerOptions::EFFECT_TORNADO], true);
+ FLOAT_INTERFACE(Tipsy, Effects[PlayerOptions::EFFECT_TIPSY], true);
+ FLOAT_INTERFACE(Bumpy, Effects[PlayerOptions::EFFECT_BUMPY], true);
+ FLOAT_INTERFACE(Beat, Effects[PlayerOptions::EFFECT_BEAT], true);
+ FLOAT_INTERFACE(Xmode, Effects[PlayerOptions::EFFECT_XMODE], true);
+ FLOAT_INTERFACE(Twirl, Effects[PlayerOptions::EFFECT_TWIRL], true);
+ FLOAT_INTERFACE(Roll, Effects[PlayerOptions::EFFECT_ROLL], true);
+ FLOAT_INTERFACE(Hidden, Appearances[PlayerOptions::APPEARANCE_HIDDEN], true);
+ FLOAT_INTERFACE(HiddenOffset, Appearances[PlayerOptions::APPEARANCE_HIDDEN_OFFSET], true);
+ FLOAT_INTERFACE(Sudden, Appearances[PlayerOptions::APPEARANCE_SUDDEN], true);
+ FLOAT_INTERFACE(SuddenOffset, Appearances[PlayerOptions::APPEARANCE_SUDDEN_OFFSET], true);
+ FLOAT_INTERFACE(Stealth, Appearances[PlayerOptions::APPEARANCE_STEALTH], true);
+ FLOAT_INTERFACE(Blink, Appearances[PlayerOptions::APPEARANCE_BLINK], true);
+ FLOAT_INTERFACE(RandomVanish, Appearances[PlayerOptions::APPEARANCE_RANDOMVANISH], true);
+ FLOAT_INTERFACE(Reverse, Scrolls[PlayerOptions::SCROLL_REVERSE], true);
+ FLOAT_INTERFACE(Split, Scrolls[PlayerOptions::SCROLL_SPLIT], true);
+ FLOAT_INTERFACE(Alternate, Scrolls[PlayerOptions::SCROLL_ALTERNATE], true);
+ FLOAT_INTERFACE(Cross, Scrolls[PlayerOptions::SCROLL_CROSS], true);
+ FLOAT_INTERFACE(Centered, Scrolls[PlayerOptions::SCROLL_CENTERED], true);
+ FLOAT_INTERFACE(Dark, Dark, true);
+ FLOAT_INTERFACE(Blind, Blind, true);
+ FLOAT_INTERFACE(Cover, Cover, true);
+ FLOAT_INTERFACE(RandAttack, RandAttack, true);
+ FLOAT_INTERFACE(NoAttack, NoAttack, true);
+ FLOAT_INTERFACE(PlayerAutoPlay, PlayerAutoPlay, true);
+ FLOAT_INTERFACE(Skew, Skew, true);
+ FLOAT_INTERFACE(Tilt, PerspectiveTilt, true);
+ FLOAT_INTERFACE(Passmark, Passmark, true); // Passmark is not sanity checked to the [0, 1] range because LifeMeterBar::IsFailing is the only thing that uses it, and it's used in a <= test. Any theme passing a value outside the [0, 1] range probably expects the result they get. -Kyz
+ FLOAT_INTERFACE(RandomSpeed, RandomSpeed, true);
BOOL_INTERFACE(TurnNone, Turns[PlayerOptions::TURN_NONE]);
BOOL_INTERFACE(Mirror, Turns[PlayerOptions::TURN_MIRROR]);
BOOL_INTERFACE(Backwards, Turns[PlayerOptions::TURN_BACKWARDS]);
@@ -1063,9 +1010,7 @@ public:
BOOL_INTERFACE(NoQuads, Transforms[PlayerOptions::TRANSFORM_NOQUADS]);
BOOL_INTERFACE(NoStretch, Transforms[PlayerOptions::TRANSFORM_NOSTRETCH]);
BOOL_INTERFACE(MuteOnError, MuteOnError);
-
-#undef FLOAT_INTERFACE
-#undef BOOL_INTERFACE
+ ENUM_INTERFACE(FailSetting, FailType, FailType);
// NoteSkins
static int NoteSkin(T* p, lua_State* L)
@@ -1098,17 +1043,6 @@ public:
return 2;
}
- static int FailSetting(T* p, lua_State* L)
- {
- DefaultNilArgs(L, 1);
- Enum::Push(L, p->m_FailType);
- if(lua_isstring(L, 1))
- {
- p->m_FailType= Enum::Check(L, 1);
- }
- return 1;
- }
-
static void SetSpeedModApproaches(T* p, float speed)
{
p->m_SpeedfScrollBPM= speed;
@@ -1147,7 +1081,7 @@ public:
}
if(lua_isnumber(L, 2))
{
- SetSpeedModApproaches(p, CheckedApproachSpeed(L, FArg(2)));
+ SetSpeedModApproaches(p, FArgGTEZero(L, 2));
}
return 2;
}
@@ -1174,7 +1108,7 @@ public:
}
if(lua_isnumber(L, 2))
{
- SetSpeedModApproaches(p, CheckedApproachSpeed(L, FArg(2)));
+ SetSpeedModApproaches(p, FArgGTEZero(L, 2));
}
return 2;
}
@@ -1206,7 +1140,7 @@ public:
}
if(lua_isnumber(L, 2))
{
- SetSpeedModApproaches(p, CheckedApproachSpeed(L, FArg(2)));
+ SetSpeedModApproaches(p, FArgGTEZero(L, 2));
}
return 2;
}
@@ -1228,7 +1162,7 @@ public:
}
if(lua_isnumber(L, 2))
{
- SetPerspectiveApproach(p, L, CheckedApproachSpeed(L, FArg(2)));
+ SetPerspectiveApproach(p, L, FArgGTEZero(L, 2));
}
return 1;
}
@@ -1255,7 +1189,7 @@ public:
}
if(lua_isnumber(L, 2))
{
- SetPerspectiveApproach(p, L, CheckedApproachSpeed(L, FArg(2)));
+ SetPerspectiveApproach(p, L, FArgGTEZero(L, 2));
}
return 2;
}
@@ -1282,7 +1216,7 @@ public:
}
if(lua_isnumber(L, 2))
{
- SetPerspectiveApproach(p, L, CheckedApproachSpeed(L, FArg(2)));
+ SetPerspectiveApproach(p, L, FArgGTEZero(L, 2));
}
return 2;
}
@@ -1307,7 +1241,7 @@ public:
}
if(lua_isnumber(L, 2))
{
- SetPerspectiveApproach(p, L, CheckedApproachSpeed(L, FArg(2)));
+ SetPerspectiveApproach(p, L, FArgGTEZero(L, 2));
}
return 2;
}
@@ -1332,7 +1266,7 @@ public:
}
if(lua_isnumber(L, 2))
{
- SetPerspectiveApproach(p, L, CheckedApproachSpeed(L, FArg(2)));
+ SetPerspectiveApproach(p, L, FArgGTEZero(L, 2));
}
return 2;
}
diff --git a/src/ScreenDebugOverlay.cpp b/src/ScreenDebugOverlay.cpp
index 68204bd00c..3cdfe08a9f 100644
--- a/src/ScreenDebugOverlay.cpp
+++ b/src/ScreenDebugOverlay.cpp
@@ -647,28 +647,28 @@ class DebugLineAutosync : public IDebugLine
virtual RString GetDisplayTitle() { return AUTOSYNC.GetValue(); }
virtual RString GetDisplayValue()
{
- SongOptions::AutosyncType type = GAMESTATE->m_SongOptions.GetSong().m_AutosyncType;
+ AutosyncType type = GAMESTATE->m_SongOptions.GetSong().m_AutosyncType;
switch( type )
{
- case SongOptions::AUTOSYNC_OFF: return OFF.GetValue(); break;
- case SongOptions::AUTOSYNC_SONG: return SONG.GetValue(); break;
- case SongOptions::AUTOSYNC_MACHINE: return MACHINE.GetValue(); break;
- case SongOptions::AUTOSYNC_TEMPO: return SYNC_TEMPO.GetValue(); break;
+ case AutosyncType_Off: return OFF.GetValue(); break;
+ case AutosyncType_Song: return SONG.GetValue(); break;
+ case AutosyncType_Machine: return MACHINE.GetValue(); break;
+ case AutosyncType_Tempo: return SYNC_TEMPO.GetValue(); break;
default:
FAIL_M(ssprintf("Invalid autosync type: %i", type));
}
}
virtual Type GetType() const { return IDebugLine::gameplay_only; }
- virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_AutosyncType!=SongOptions::AUTOSYNC_OFF; }
+ virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_AutosyncType!=AutosyncType_Off; }
virtual void DoAndLog( RString &sMessageOut )
{
int as = GAMESTATE->m_SongOptions.GetSong().m_AutosyncType + 1;
bool bAllowSongAutosync = !GAMESTATE->IsCourseMode();
if( !bAllowSongAutosync &&
- ( as == SongOptions::AUTOSYNC_SONG || as == SongOptions::AUTOSYNC_TEMPO ) )
- as = SongOptions::AUTOSYNC_MACHINE;
- wrap( as, SongOptions::NUM_AUTOSYNC_TYPES );
- SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_AutosyncType, SongOptions::AutosyncType(as) );
+ ( as == AutosyncType_Song || as == AutosyncType_Tempo ) )
+ as = AutosyncType_Machine;
+ wrap( as, NUM_AutosyncType );
+ SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_AutosyncType, AutosyncType(as) );
MESSAGEMAN->Broadcast( Message_AutosyncChanged );
IDebugLine::DoAndLog( sMessageOut );
}
diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp
index efae737af1..ed67500d1b 100644
--- a/src/ScreenGameplay.cpp
+++ b/src/ScreenGameplay.cpp
@@ -135,7 +135,7 @@ void PlayerInfo::Load( PlayerNumber pn, MultiPlayer mp, bool bShowNoteField, int
break;
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
- if( GAMESTATE->m_SongOptions.GetStage().m_LifeType == SongOptions::LIFE_TIME )
+ if( GAMESTATE->m_SongOptions.GetStage().m_LifeType == LifeType_Time )
m_pPrimaryScoreDisplay = new ScoreDisplayLifeTime;
else
m_pPrimaryScoreDisplay = new ScoreDisplayOni;
@@ -570,7 +570,7 @@ void ScreenGameplay::Init()
// not 100% sure of that. -freem
if( !GAMESTATE->IsPlayerEnabled(pi->m_pn) && SHOW_LIFE_METER_FOR_DISABLED_PLAYERS )
{
- if(GAMESTATE->m_SongOptions.GetStage().m_LifeType == SongOptions::LIFE_BAR)
+ if(GAMESTATE->m_SongOptions.GetStage().m_LifeType == LifeType_Bar)
static_cast(pi->m_pLifeMeter)->ChangeLife(-1.0f);
}
}
@@ -1017,9 +1017,9 @@ void ScreenGameplay::SetupSong( int iSongIndex )
RString sType;
switch( GAMESTATE->m_SongOptions.GetCurrent().m_SoundEffectType )
{
- case SongOptions::SOUNDEFFECT_OFF: sType = "SoundEffectControl_Off"; break;
- case SongOptions::SOUNDEFFECT_SPEED: sType = "SoundEffectControl_Speed"; break;
- case SongOptions::SOUNDEFFECT_PITCH: sType = "SoundEffectControl_Pitch"; break;
+ case SoundEffectType_Off: sType = "SoundEffectControl_Off"; break;
+ case SoundEffectType_Speed: sType = "SoundEffectControl_Speed"; break;
+ case SoundEffectType_Pitch: sType = "SoundEffectControl_Pitch"; break;
default: break;
}
@@ -1082,7 +1082,7 @@ void ScreenGameplay::LoadNextSong()
/* If we're in battery mode, force FailImmediate. We assume in Player::Step
* that failed players can't step. */
- if( GAMESTATE->m_SongOptions.GetCurrent().m_LifeType == SongOptions::LIFE_BATTERY )
+ if( GAMESTATE->m_SongOptions.GetCurrent().m_LifeType == LifeType_Battery )
{
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
PO_GROUP_ASSIGN( pi->GetPlayerState()->m_PlayerOptions, ModsLevel_Song, m_FailType, FailType_Immediate );
@@ -1118,10 +1118,10 @@ void ScreenGameplay::LoadNextSong()
// reset oni game over graphic
SET_XY_AND_ON_COMMAND( pi->m_sprOniGameOver );
- if( GAMESTATE->m_SongOptions.GetCurrent().m_LifeType==SongOptions::LIFE_BATTERY && pi->GetPlayerStageStats()->m_bFailed ) // already failed
+ if( GAMESTATE->m_SongOptions.GetCurrent().m_LifeType==LifeType_Battery && pi->GetPlayerStageStats()->m_bFailed ) // already failed
pi->ShowOniGameOver();
- if( GAMESTATE->m_SongOptions.GetCurrent().m_LifeType==SongOptions::LIFE_BAR && pi->m_pLifeMeter )
+ if( GAMESTATE->m_SongOptions.GetCurrent().m_LifeType==LifeType_Bar && pi->m_pLifeMeter )
pi->m_pLifeMeter->UpdateNonstopLifebar();
if( pi->m_pStepsDisplay )
@@ -1634,7 +1634,7 @@ void ScreenGameplay::Update( float fDeltaTime )
PlayerNumber pn = pi->GetStepsAndTrailIndex();
FailType ft = GAMESTATE->GetPlayerFailType( pi->GetPlayerState() );
- SongOptions::LifeType lt = GAMESTATE->m_SongOptions.GetCurrent().m_LifeType;
+ LifeType lt = GAMESTATE->m_SongOptions.GetCurrent().m_LifeType;
if( ft == FailType_Off || ft == FailType_EndOfSong )
continue;
@@ -1658,7 +1658,7 @@ void ScreenGameplay::Update( float fDeltaTime )
bool bAllowOniDie = false;
switch( lt )
{
- case SongOptions::LIFE_BATTERY:
+ case LifeType_Battery:
bAllowOniDie = true;
default:
break;
diff --git a/src/ScreenGameplaySyncMachine.cpp b/src/ScreenGameplaySyncMachine.cpp
index 037ced9f97..24456d85bf 100644
--- a/src/ScreenGameplaySyncMachine.cpp
+++ b/src/ScreenGameplaySyncMachine.cpp
@@ -45,7 +45,7 @@ void ScreenGameplaySyncMachine::Init()
ScreenGameplayNormal::Init();
- SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_AutosyncType, SongOptions::AUTOSYNC_MACHINE );
+ SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_AutosyncType, AutosyncType_Machine );
ClearMessageQueue(); // remove all of the messages set in ScreenGameplay that animate "ready", "here we go", etc.
diff --git a/src/ScreenJukebox.cpp b/src/ScreenJukebox.cpp
index 6176a50ebe..925e9fb209 100644
--- a/src/ScreenJukebox.cpp
+++ b/src/ScreenJukebox.cpp
@@ -198,7 +198,7 @@ void ScreenJukebox::Init()
PO_GROUP_ASSIGN( GAMESTATE->m_pPlayerState[p]->m_PlayerOptions, ModsLevel_Stage, m_fPerspectiveTilt, -1.0f );
PO_GROUP_ASSIGN_N( GAMESTATE->m_pPlayerState[p]->m_PlayerOptions, ModsLevel_Stage, m_fEffects, PlayerOptions::EFFECT_TINY, 1.0f );
}
- SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_LifeType, SongOptions::LIFE_BATTERY );
+ SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_LifeType, LifeType_Battery );
}
FOREACH_EnabledPlayer( p )
diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp
index 48e01e7a77..89045a53b2 100644
--- a/src/ScreenSelectMusic.cpp
+++ b/src/ScreenSelectMusic.cpp
@@ -1247,11 +1247,11 @@ bool ScreenSelectMusic::MenuStart( const InputEventPlus &input )
// apply #LIVES
if( pCourse->m_iLives != -1 )
{
- SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_LifeType, SongOptions::LIFE_BATTERY );
+ SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_LifeType, LifeType_Battery );
SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_iBatteryLives, pCourse->m_iLives );
}
if( pCourse->GetCourseType() == COURSE_TYPE_SURVIVAL)
- SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_LifeType, SongOptions::LIFE_TIME );
+ SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Stage, m_LifeType, LifeType_Time );
}
else
{
diff --git a/src/ScreenSyncOverlay.cpp b/src/ScreenSyncOverlay.cpp
index b0ba604e4b..be23fc1c08 100644
--- a/src/ScreenSyncOverlay.cpp
+++ b/src/ScreenSyncOverlay.cpp
@@ -113,13 +113,13 @@ void ScreenSyncOverlay::UpdateText()
}
}
- SongOptions::AutosyncType type = GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType;
+ AutosyncType type = GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType;
switch( type )
{
- case SongOptions::AUTOSYNC_OFF: break;
- case SongOptions::AUTOSYNC_SONG: vs.push_back(AUTO_SYNC_SONG); break;
- case SongOptions::AUTOSYNC_MACHINE: vs.push_back(AUTO_SYNC_MACHINE); break;
- case SongOptions::AUTOSYNC_TEMPO: vs.push_back(AUTO_SYNC_TEMPO); break;
+ case AutosyncType_Off: break;
+ case AutosyncType_Song: vs.push_back(AUTO_SYNC_SONG); break;
+ case AutosyncType_Machine: vs.push_back(AUTO_SYNC_MACHINE); break;
+ case AutosyncType_Tempo: vs.push_back(AUTO_SYNC_TEMPO); break;
default:
FAIL_M(ssprintf("Invalid autosync type: %i", type));
}
@@ -134,7 +134,7 @@ void ScreenSyncOverlay::UpdateText()
// Update SyncInfo
- bool bVisible = GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType != SongOptions::AUTOSYNC_OFF;
+ bool bVisible = GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType != AutosyncType_Off;
m_textAdjustments.SetVisible( bVisible );
if( bVisible )
{
diff --git a/src/SongOptions.cpp b/src/SongOptions.cpp
index 6580f729a0..360b96505e 100644
--- a/src/SongOptions.cpp
+++ b/src/SongOptions.cpp
@@ -4,10 +4,47 @@
#include "GameState.h"
#include "CommonMetrics.h"
+static const char *LifeTypeNames[] = {
+ "Bar",
+ "Battery",
+ "Time",
+};
+XToString( LifeType );
+XToLocalizedString( LifeType );
+LuaXType( LifeType );
+
+static const char *DrainTypeNames[] = {
+ "Normal",
+ "NoRecover",
+ "SuddenDeath",
+};
+XToString( DrainType );
+XToLocalizedString( DrainType );
+LuaXType( DrainType );
+
+static const char *AutosyncTypeNames[] = {
+ "Off",
+ "Song",
+ "Machine",
+ "Tempo",
+};
+XToString( AutosyncType );
+XToLocalizedString( AutosyncType );
+LuaXType( AutosyncType );
+
+static const char *SoundEffectTypeNames[] = {
+ "Off",
+ "Speed",
+ "Pitch",
+};
+XToString( SoundEffectType );
+XToLocalizedString( SoundEffectType );
+LuaXType( SoundEffectType );
+
void SongOptions::Init()
{
- m_LifeType = LIFE_BAR;
- m_DrainType = DRAIN_NORMAL;
+ m_LifeType = LifeType_Bar;
+ m_DrainType = DrainType_Normal;
m_iBatteryLives = 4;
m_bAssistClap = false;
m_bAssistMetronome = false;
@@ -15,8 +52,8 @@ void SongOptions::Init()
m_SpeedfMusicRate = 1.0f;
m_fHaste = 0.0f;
m_SpeedfHaste = 1.0f;
- m_AutosyncType = AUTOSYNC_OFF;
- m_SoundEffectType = SOUNDEFFECT_OFF;
+ m_AutosyncType = AutosyncType_Off;
+ m_SoundEffectType = SoundEffectType_Off;
m_bStaticBackground = false;
m_bRandomBGOnly = false;
m_bSaveScore = true;
@@ -61,18 +98,18 @@ void SongOptions::GetMods( vector &AddTo ) const
{
switch( m_LifeType )
{
- case LIFE_BAR:
+ case LifeType_Bar:
switch( m_DrainType )
{
- case DRAIN_NORMAL: break;
- case DRAIN_NO_RECOVER: AddTo.push_back("NoRecover"); break;
- case DRAIN_SUDDEN_DEATH: AddTo.push_back("SuddenDeath"); break;
+ case DrainType_Normal: break;
+ case DrainType_NoRecover: AddTo.push_back("NoRecover"); break;
+ case DrainType_SuddenDeath: AddTo.push_back("SuddenDeath"); break;
}
break;
- case LIFE_BATTERY:
+ case LifeType_Battery:
AddTo.push_back( ssprintf( "%dLives", m_iBatteryLives ) );
break;
- case LIFE_TIME:
+ case LifeType_Time:
AddTo.push_back( "LifeTime" );
break;
default:
@@ -92,19 +129,19 @@ void SongOptions::GetMods( vector &AddTo ) const
switch( m_AutosyncType )
{
- case AUTOSYNC_OFF: break;
- case AUTOSYNC_SONG: AddTo.push_back("AutosyncSong"); break;
- case AUTOSYNC_MACHINE: AddTo.push_back("AutosyncMachine"); break;
- case AUTOSYNC_TEMPO: AddTo.push_back("AutosyncTempo"); break;
+ case AutosyncType_Off: break;
+ case AutosyncType_Song: AddTo.push_back("AutosyncSong"); break;
+ case AutosyncType_Machine: AddTo.push_back("AutosyncMachine"); break;
+ case AutosyncType_Tempo: AddTo.push_back("AutosyncTempo"); break;
default:
FAIL_M(ssprintf("Invalid autosync type: %i", m_AutosyncType));
}
switch( m_SoundEffectType )
{
- case SOUNDEFFECT_OFF: break;
- case SOUNDEFFECT_SPEED: AddTo.push_back("EffectSpeed"); break;
- case SOUNDEFFECT_PITCH: AddTo.push_back("EffectPitch"); break;
+ case SoundEffectType_Off: break;
+ case SoundEffectType_Speed: AddTo.push_back("EffectSpeed"); break;
+ case SoundEffectType_Pitch: AddTo.push_back("EffectPitch"); break;
default:
FAIL_M(ssprintf("Invalid sound effect type: %i", m_SoundEffectType));
}
@@ -190,26 +227,26 @@ bool SongOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut )
on = false;
}
- if( sBit == "norecover" ) m_DrainType = DRAIN_NO_RECOVER;
- else if( sBit == "suddendeath" || sBit == "death" ) m_DrainType = DRAIN_SUDDEN_DEATH;
- else if( sBit == "power-drop" ) m_DrainType = DRAIN_NO_RECOVER;
- else if( sBit == "normal-drain" ) m_DrainType = DRAIN_NORMAL;
+ if( sBit == "norecover" ) m_DrainType = DrainType_NoRecover;
+ else if( sBit == "suddendeath" || sBit == "death" ) m_DrainType = DrainType_SuddenDeath;
+ else if( sBit == "power-drop" ) m_DrainType = DrainType_NoRecover;
+ else if( sBit == "normal-drain" ) m_DrainType = DrainType_Normal;
else if( sBit == "clap" ) m_bAssistClap = on;
else if( sBit == "metronome" ) m_bAssistMetronome = on;
- else if( sBit == "autosync" || sBit == "autosyncsong" ) m_AutosyncType = on ? AUTOSYNC_SONG : AUTOSYNC_OFF;
- else if( sBit == "autosyncmachine" ) m_AutosyncType = on ? AUTOSYNC_MACHINE : AUTOSYNC_OFF;
- else if( sBit == "autosynctempo" ) m_AutosyncType = on ? AUTOSYNC_TEMPO : AUTOSYNC_OFF;
- else if( sBit == "effect" && !on ) m_SoundEffectType = SOUNDEFFECT_OFF;
- else if( sBit == "effectspeed" ) m_SoundEffectType = on ? SOUNDEFFECT_SPEED : SOUNDEFFECT_OFF;
- else if( sBit == "effectpitch" ) m_SoundEffectType = on ? SOUNDEFFECT_PITCH : SOUNDEFFECT_OFF;
+ else if( sBit == "autosync" || sBit == "autosyncsong" ) m_AutosyncType = on ? AutosyncType_Song : AutosyncType_Off;
+ else if( sBit == "autosyncmachine" ) m_AutosyncType = on ? AutosyncType_Machine : AutosyncType_Off;
+ else if( sBit == "autosynctempo" ) m_AutosyncType = on ? AutosyncType_Tempo : AutosyncType_Off;
+ else if( sBit == "effect" && !on ) m_SoundEffectType = SoundEffectType_Off;
+ else if( sBit == "effectspeed" ) m_SoundEffectType = on ? SoundEffectType_Speed : SoundEffectType_Off;
+ else if( sBit == "effectpitch" ) m_SoundEffectType = on ? SoundEffectType_Pitch : SoundEffectType_Off;
else if( sBit == "staticbg" ) m_bStaticBackground = on;
else if( sBit == "randombg" ) m_bRandomBGOnly = on;
else if( sBit == "savescore" ) m_bSaveScore = on;
else if( sBit == "savereplay" ) m_bSaveReplay = on;
- else if( sBit == "bar" ) m_LifeType = LIFE_BAR;
- else if( sBit == "battery" ) m_LifeType = LIFE_BATTERY;
- else if( sBit == "lifetime" ) m_LifeType = LIFE_TIME;
+ else if( sBit == "bar" ) m_LifeType = LifeType_Bar;
+ else if( sBit == "battery" ) m_LifeType = LifeType_Battery;
+ else if( sBit == "lifetime" ) m_LifeType = LifeType_Time;
else if( sBit == "haste" ) m_fHaste = on? 1.0f:0.0f;
else
return false;
@@ -237,6 +274,51 @@ bool SongOptions::operator==( const SongOptions &other ) const
return true;
}
+// lua start
+#include "LuaBinding.h"
+#include "OptionsBinding.h"
+
+/** @brief Allow Lua to have access to SongOptions. */
+class LunaSongOptions: public Luna
+{
+public:
+
+ ENUM_INTERFACE(LifeSetting, LifeType, LifeType);
+ ENUM_INTERFACE(DrainSetting, DrainType, DrainType);
+ ENUM_INTERFACE(AutosyncSetting, AutosyncType, AutosyncType);
+ //ENUM_INTERFACE(SoundEffectSetting, SoundEffectType, SoundEffectType);
+ // Broken, SoundEffectType_Speed disables rate mod, other settings have no effect. -Kyz
+ INT_INTERFACE(BatteryLives, BatteryLives);
+ BOOL_INTERFACE(AssistClap, AssistClap);
+ BOOL_INTERFACE(AssistMetronome, AssistMetronome);
+ BOOL_INTERFACE(StaticBackground, StaticBackground);
+ BOOL_INTERFACE(RandomBGOnly, RandomBGOnly);
+ BOOL_INTERFACE(SaveScore, SaveScore);
+ BOOL_INTERFACE(SaveReplay, SaveReplay);
+ FLOAT_INTERFACE(MusicRate, MusicRate, (v > 0.0f && v <= 3.0f)); // Greater than 3 seems to crash frequently, haven't investigated why. -Kyz
+ FLOAT_INTERFACE(Haste, Haste, true);
+
+ LunaSongOptions()
+ {
+ ADD_METHOD(LifeSetting);
+ ADD_METHOD(DrainSetting);
+ ADD_METHOD(AutosyncSetting);
+ //ADD_METHOD(SoundEffectSetting);
+ ADD_METHOD(BatteryLives);
+ ADD_METHOD(AssistClap);
+ ADD_METHOD(AssistMetronome);
+ ADD_METHOD(StaticBackground);
+ ADD_METHOD(RandomBGOnly);
+ ADD_METHOD(SaveScore);
+ ADD_METHOD(SaveReplay);
+ ADD_METHOD(MusicRate);
+ ADD_METHOD(Haste);
+ }
+};
+
+LUA_REGISTER_CLASS( SongOptions )
+// lua end
+
/*
* (c) 2001-2004 Chris Danford, Glenn Maynard
* All rights reserved.
diff --git a/src/SongOptions.h b/src/SongOptions.h
index 9bb88f4236..9d2c93d911 100644
--- a/src/SongOptions.h
+++ b/src/SongOptions.h
@@ -3,43 +3,68 @@
#ifndef SONG_OPTIONS_H
#define SONG_OPTIONS_H
+#include "EnumHelper.h"
+
+enum LifeType
+{
+ LifeType_Bar,
+ LifeType_Battery,
+ LifeType_Time,
+ NUM_LifeType,
+ LifeType_Invalid
+};
+const RString& LifeTypeToString( LifeType cat );
+const RString& LifeTypeToLocalizedString( LifeType cat );
+LuaDeclareType( LifeType );
+
+enum DrainType
+{
+ DrainType_Normal,
+ DrainType_NoRecover,
+ DrainType_SuddenDeath,
+ NUM_DrainType,
+ DrainType_Invalid
+};
+const RString& DrainTypeToString( DrainType cat );
+const RString& DrainTypeToLocalizedString( DrainType cat );
+LuaDeclareType( DrainType );
+
+enum AutosyncType
+{
+ AutosyncType_Off,
+ AutosyncType_Song,
+ AutosyncType_Machine,
+ AutosyncType_Tempo,
+ NUM_AutosyncType,
+ AutosyncType_Invalid
+};
+const RString& AutosyncTypeToString( AutosyncType cat );
+const RString& AutosyncTypeToLocalizedString( AutosyncType cat );
+LuaDeclareType( AutosyncType );
+
+enum SoundEffectType
+{
+ SoundEffectType_Off,
+ SoundEffectType_Speed,
+ SoundEffectType_Pitch,
+ NUM_SoundEffectType,
+ SoundEffectType_Invalid
+};
+const RString& SoundEffectTypeToString( SoundEffectType cat );
+const RString& SoundEffectTypeToLocalizedString( SoundEffectType cat );
+LuaDeclareType( SoundEffectType );
+
class SongOptions
{
public:
- enum LifeType
- {
- LIFE_BAR=0,
- LIFE_BATTERY,
- LIFE_TIME,
- NUM_LIFE_TYPES
- };
LifeType m_LifeType;
- enum DrainType
- {
- DRAIN_NORMAL,
- DRAIN_NO_RECOVER,
- DRAIN_SUDDEN_DEATH
- };
DrainType m_DrainType; // only used with LifeBar
int m_iBatteryLives;
bool m_bAssistClap;
bool m_bAssistMetronome;
float m_fMusicRate, m_SpeedfMusicRate;
float m_fHaste, m_SpeedfHaste;
- enum AutosyncType {
- AUTOSYNC_OFF,
- AUTOSYNC_SONG,
- AUTOSYNC_MACHINE,
- AUTOSYNC_TEMPO,
- NUM_AUTOSYNC_TYPES
- };
AutosyncType m_AutosyncType;
- enum SoundEffectType {
- SOUNDEFFECT_OFF,
- SOUNDEFFECT_SPEED,
- SOUNDEFFECT_PITCH,
- NUM_SOUNDEFFECT
- };
SoundEffectType m_SoundEffectType;
bool m_bStaticBackground;
bool m_bRandomBGOnly;
@@ -51,12 +76,12 @@ public:
*
* This is taken from Init(), but uses the intended
* initialization lists. */
- SongOptions(): m_LifeType(LIFE_BAR), m_DrainType(DRAIN_NORMAL),
+ SongOptions(): m_LifeType(LifeType_Bar), m_DrainType(DrainType_Normal),
m_iBatteryLives(4), m_bAssistClap(false),
m_bAssistMetronome(false), m_fMusicRate(1.0f),
m_SpeedfMusicRate(1.0f), m_fHaste(0.0f),
- m_SpeedfHaste(1.0f), m_AutosyncType(AUTOSYNC_OFF),
- m_SoundEffectType(SOUNDEFFECT_OFF),
+ m_SpeedfHaste(1.0f), m_AutosyncType(AutosyncType_Off),
+ m_SoundEffectType(SoundEffectType_Off),
m_bStaticBackground(false), m_bRandomBGOnly(false),
m_bSaveScore(true), m_bSaveReplay(false) {};
void Init();
@@ -70,6 +95,9 @@ public:
bool operator==( const SongOptions &other ) const;
bool operator!=( const SongOptions &other ) const { return !operator==(other); }
+
+ // Lua
+ void PushSelf( lua_State *L );
};
#endif