Changed default ScreenSelecStyle to use functions for choice names and positions instead of metrics. _fallback SSS remains the same for compatibility. Fixed style stomping bug in SetCompatibleStylesForPlayers.
This commit is contained in:
+35
-9
@@ -4,6 +4,32 @@ The StepMania 5 Changelog covers all post-sm-ssc changes. For a list of changes
|
|||||||
from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt.
|
from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt.
|
||||||
________________________________________________________________________________
|
________________________________________________________________________________
|
||||||
|
|
||||||
|
2015/01/20
|
||||||
|
----------
|
||||||
|
* [ScreenSelect] ChoiceNames can be a lua command that is evaluated to get a
|
||||||
|
list of the gamecommands. The main use of this is to get rid of the huge
|
||||||
|
list of metrics that ScreenSelectStyle requires. A single lua function
|
||||||
|
instead of a metric for every style for every game type. [kyzentun]
|
||||||
|
* [ScreenSelectMaster] IconChoicePosFunction metric added. This metric is
|
||||||
|
optional, if it's set, it must be set to a function that returns a table
|
||||||
|
of positions. Each position is a table of the form "{x, y, z}", where x,
|
||||||
|
y, and z are numbers and any that is not a number defaults to 0.
|
||||||
|
The function is passed the number of choices for the screen.
|
||||||
|
IconChoiceOnCommand and IconChoiceOffCommand metrics added so each choice
|
||||||
|
doesn't require its own On/OffCommand pair. These are also optional, but
|
||||||
|
if they are set, they will override the individual commands if they exist.
|
||||||
|
(If "IconChoiceCactusOnCommand" and "IconChoiceOnCommand" both exist,
|
||||||
|
"IconChoiceOnCommand" will be used.) [kyzentun]
|
||||||
|
Example:
|
||||||
|
# in metrics.ini
|
||||||
|
IconChoicePosFunction=choice_positions
|
||||||
|
-- In a file in Scripts/
|
||||||
|
function choice_positions(count)
|
||||||
|
local ret= {}
|
||||||
|
for i= 1, ret do ret[i]= {i*24, i*48} end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
2014/12/10
|
2014/12/10
|
||||||
----------
|
----------
|
||||||
* [EditMode] Play whole song and play from current beat will now play until
|
* [EditMode] Play whole song and play from current beat will now play until
|
||||||
@@ -22,20 +48,20 @@ ________________________________________________________________________________
|
|||||||
* [GameManager] Lua Scripts/ folders are now reloaded when the Game mode is
|
* [GameManager] Lua Scripts/ folders are now reloaded when the Game mode is
|
||||||
changed. [kyzentun]
|
changed. [kyzentun]
|
||||||
* [GameState] CanSafelyEnterGameplay function added. [kyzentun]
|
* [GameState] CanSafelyEnterGameplay function added. [kyzentun]
|
||||||
In kickbox game mode, players can have different styles set, pass a
|
In kickbox game mode, players can have different styles set, pass a
|
||||||
PlayerNumber when using SetCurrentStyle or GetCurrentStyle.
|
PlayerNumber when using SetCurrentStyle or GetCurrentStyle.
|
||||||
* [kickbox] New game mode with 4 styles. [kyzentun]
|
* [kickbox] New game mode with 4 styles. [kyzentun]
|
||||||
* [ScreenGameplay] Notefield positioning is handled a bit differently now.
|
* [ScreenGameplay] Notefield positioning is handled a bit differently now.
|
||||||
See comments in _fallback/metrics.ini above the [ScreenGameplay]
|
See comments in _fallback/metrics.ini above the [ScreenGameplay]
|
||||||
MarginFunction metric. Basically, you can define a lua function that
|
MarginFunction metric. Basically, you can define a lua function that
|
||||||
returns the space you want at the edges and in the center instead of
|
returns the space you want at the edges and in the center instead of
|
||||||
setting position metrics. Do NOT use Style:GetWidth to calculate the
|
setting position metrics. Do NOT use Style:GetWidth to calculate the
|
||||||
margins your function returns.
|
margins your function returns.
|
||||||
ScreenGameplay now handles zooming the notefield to fit in the space
|
ScreenGameplay now handles zooming the notefield to fit in the space
|
||||||
instead of using the NeedsZoomOutWith2Players flag in the style.
|
instead of using the NeedsZoomOutWith2Players flag in the style.
|
||||||
If the notefield doesn't fit in the space between the margins, and there is
|
If the notefield doesn't fit in the space between the margins, and there is
|
||||||
only one player, the player will be centered even if the Center1Player pref
|
only one player, the player will be centered even if the Center1Player pref
|
||||||
is false. [kyzentun]
|
is false. [kyzentun]
|
||||||
* [Style] NeedsZoomOutWith2Players decapitated. Always returns false now.
|
* [Style] NeedsZoomOutWith2Players decapitated. Always returns false now.
|
||||||
GetWidth added. [kyzentun]
|
GetWidth added. [kyzentun]
|
||||||
* [techno] Techno game mode no longer has special column width for versus.
|
* [techno] Techno game mode no longer has special column width for versus.
|
||||||
@@ -74,7 +100,7 @@ ________________________________________________________________________________
|
|||||||
a new profile was created fixed. [kyzentun]
|
a new profile was created fixed. [kyzentun]
|
||||||
* [Everything] Actor and singleton functions that formerly returned nothing now
|
* [Everything] Actor and singleton functions that formerly returned nothing now
|
||||||
return the actor or singleton. Example (set zoom, x, y, and diffuse in one):
|
return the actor or singleton. Example (set zoom, x, y, and diffuse in one):
|
||||||
self:zoom(.5):xy(_screen.cx, _screen.h-60):diffuse(color("#dc322f"))
|
self:zoom(.5):xy(_screen.cx, _screen.h-60):diffuse(color("#dc322f"))
|
||||||
This also works for PlayerOptions and SongOptions API functions. Pass true
|
This also works for PlayerOptions and SongOptions API functions. Pass true
|
||||||
as an extra arg, and they can be chained.
|
as an extra arg, and they can be chained.
|
||||||
|
|
||||||
|
|||||||
@@ -107,6 +107,46 @@ function GameCompatibleModes()
|
|||||||
return Modes[CurGameName()]
|
return Modes[CurGameName()]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function upper_first_letter(s)
|
||||||
|
local first_letter= s:match("([a-zA-Z])")
|
||||||
|
return s:gsub(first_letter, first_letter:upper(), 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- No more having a metric for every style for every game mode. -Kyz
|
||||||
|
function ScreenSelectStyleChoices()
|
||||||
|
local styles= GAMEMAN:GetStylesForGame(GAMESTATE:GetCurrentGame():GetName())
|
||||||
|
local choices= {}
|
||||||
|
for i, style in ipairs(styles) do
|
||||||
|
local name= style:GetName()
|
||||||
|
local cap_name= upper_first_letter(name)
|
||||||
|
choices[#choices+1]= "name," .. cap_name .. ";style," .. name .. ";text,"
|
||||||
|
.. cap_name .. ";screen," .. Branch.AfterSelectStyle()
|
||||||
|
end
|
||||||
|
return choices
|
||||||
|
end
|
||||||
|
|
||||||
|
-- No more having an xy for every style for every game mode. -Kyz
|
||||||
|
function ScreenSelectStylePositions(count)
|
||||||
|
local poses= {}
|
||||||
|
local columns= 1
|
||||||
|
if count > 4 then columns= 2 end
|
||||||
|
local start_y= _screen.cy - (_screen.h / (math.ceil(count/columns) / 2))
|
||||||
|
for i= 1, count do
|
||||||
|
poses[i]= {}
|
||||||
|
if i <= count/columns then
|
||||||
|
poses[i][1]= _screen.cx - 160
|
||||||
|
poses[i][2]= start_y + (96 * i)
|
||||||
|
else
|
||||||
|
poses[i][1]= _screen.cx + 160
|
||||||
|
poses[i][2]= start_y + (96 * (i-(count/2)))
|
||||||
|
end
|
||||||
|
if columns == 1 then
|
||||||
|
poses[i][1]= _screen.cx
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return poses
|
||||||
|
end
|
||||||
|
|
||||||
function SelectProfileKeys()
|
function SelectProfileKeys()
|
||||||
local sGame = CurGameName()
|
local sGame = CurGameName()
|
||||||
if sGame == "pump" then
|
if sGame == "pump" then
|
||||||
|
|||||||
@@ -1944,6 +1944,12 @@ PrevScreen=Branch.TitleMenu()
|
|||||||
TimerSeconds=30
|
TimerSeconds=30
|
||||||
#
|
#
|
||||||
DefaultChoice="Single"
|
DefaultChoice="Single"
|
||||||
|
# Giant metric list left in for backwards compatibility.
|
||||||
|
# A much better way to handle this is:
|
||||||
|
# ChoiceNames="lua,ScreenSelectStyleChoices()"
|
||||||
|
# That will list all the styles for the current game without needing a huge
|
||||||
|
# list of metrics. _fallback still uses the old method to avoid the
|
||||||
|
# possibility of breaking themes. -Kyz
|
||||||
ChoiceNames=GameCompatibleModes()
|
ChoiceNames=GameCompatibleModes()
|
||||||
#
|
#
|
||||||
OptionOrderAuto="1:2,2:1"
|
OptionOrderAuto="1:2,2:1"
|
||||||
@@ -1975,11 +1981,6 @@ ChoiceVersus8="name,Versus8;style,versus8;screen,"..Branch.AfterSelectStyle()
|
|||||||
ChoiceDouble4="name,Double4;style,double4;screen,"..Branch.AfterSelectStyle()
|
ChoiceDouble4="name,Double4;style,double4;screen,"..Branch.AfterSelectStyle()
|
||||||
ChoiceDouble5="name,Double5;style,double5;screen,"..Branch.AfterSelectStyle()
|
ChoiceDouble5="name,Double5;style,double5;screen,"..Branch.AfterSelectStyle()
|
||||||
ChoiceDouble8="name,Double8;style,double8;screen,"..Branch.AfterSelectStyle()
|
ChoiceDouble8="name,Double8;style,double8;screen,"..Branch.AfterSelectStyle()
|
||||||
# kickbox
|
|
||||||
ChoiceHuman="name,Human;style,human;screen,"..Branch.AfterSelectStyle()
|
|
||||||
ChoiceQuadarm="name,Quadarm;style,quadarm;screen,"..Branch.AfterSelectStyle()
|
|
||||||
ChoiceInsect="name,Insect;style,insect;screen,"..Branch.AfterSelectStyle()
|
|
||||||
ChoiceArachnid="name,Arachnid;style,arachnid;screen,"..Branch.AfterSelectStyle()
|
|
||||||
#
|
#
|
||||||
PerChoiceScrollElement=false
|
PerChoiceScrollElement=false
|
||||||
PerChoiceIconElement=false
|
PerChoiceIconElement=false
|
||||||
|
|||||||
@@ -771,10 +771,8 @@ FOV=90
|
|||||||
PerChoiceScrollElement=false
|
PerChoiceScrollElement=false
|
||||||
PerChoiceIconElement=false
|
PerChoiceIconElement=false
|
||||||
#
|
#
|
||||||
Choice7Keys="name,7Keys;style,single7;screen,"..Branch.AfterSelectStyle()
|
# Having one lua function is so much better than dozens of metrics. -Kyz
|
||||||
Choice10Keys="name,10Keys;style,double5;screen,"..Branch.AfterSelectStyle()
|
ChoiceNames="lua,ScreenSelectStyleChoices()"
|
||||||
Choice14Keys="name,14Keys;style,double7;screen,"..Branch.AfterSelectStyle()
|
|
||||||
ChoiceKB7="name,kb7;style,single;screen,"..Branch.AfterSelectStyle()
|
|
||||||
#
|
#
|
||||||
ShowScroller=false
|
ShowScroller=false
|
||||||
ShowIcon=true
|
ShowIcon=true
|
||||||
@@ -784,65 +782,10 @@ UseIconMetrics=true
|
|||||||
IconGainFocusCommand=stoptweening;bounceend,0.05;zoom,1;
|
IconGainFocusCommand=stoptweening;bounceend,0.05;zoom,1;
|
||||||
IconLoseFocusCommand=stoptweening;decelerate,0.1;zoom,0.8;
|
IconLoseFocusCommand=stoptweening;decelerate,0.1;zoom,0.8;
|
||||||
#
|
#
|
||||||
IconChoiceSingleX=SCREEN_CENTER_X-160
|
IconChoicePosFunction=ScreenSelectStylePositions
|
||||||
IconChoiceSingleY=SCREEN_CENTER_Y-96
|
IconChoiceOnCommand=zoom,0;bounceend,0.35;zoom,1
|
||||||
IconChoiceSingleOnCommand=zoom,0;bounceend,0.35;zoom,1
|
IconChoiceOffCommand=linear,0.05;zoomx,0
|
||||||
IconChoiceSingleOffCommand=linear,0.05;zoomx,0
|
|
||||||
#
|
#
|
||||||
IconChoiceDoubleX=SCREEN_CENTER_X-160
|
|
||||||
IconChoiceDoubleY=SCREEN_CENTER_Y
|
|
||||||
IconChoiceDoubleOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoiceDoubleOffCommand=linear,0.05;zoomx,0
|
|
||||||
####
|
|
||||||
IconChoiceSoloX=SCREEN_CENTER_X-160
|
|
||||||
IconChoiceSoloY=SCREEN_CENTER_Y+96
|
|
||||||
IconChoiceSoloOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoiceSoloOffCommand=linear,0.05;zoomx,0
|
|
||||||
#
|
|
||||||
IconChoiceHalfDoubleX=SCREEN_CENTER_X-160
|
|
||||||
IconChoiceHalfDoubleY=SCREEN_CENTER_Y+96
|
|
||||||
IconChoiceHalfDoubleOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoiceHalfDoubleOffCommand=linear,0.05;zoomx,0
|
|
||||||
####
|
|
||||||
IconChoiceVersusX=SCREEN_CENTER_X+160
|
|
||||||
IconChoiceVersusY=string.find(THEME:GetMetric("ScreenSelectStyle","ChoiceNames"),"Routine") and SCREEN_CENTER_Y-96 or SCREEN_CENTER_Y-48
|
|
||||||
IconChoiceVersusOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoiceVersusOffCommand=linear,0.05;zoomx,0
|
|
||||||
#
|
|
||||||
IconChoiceCoupleX=SCREEN_CENTER_X+160
|
|
||||||
IconChoiceCoupleY=string.find(THEME:GetMetric("ScreenSelectStyle","ChoiceNames"),"Routine") and SCREEN_CENTER_Y or SCREEN_CENTER_Y+48
|
|
||||||
IconChoiceCoupleOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoiceCoupleOffCommand=linear,0.05;zoomx,0
|
|
||||||
#
|
|
||||||
IconChoiceRoutineX=SCREEN_CENTER_X+160
|
|
||||||
IconChoiceRoutineY=SCREEN_CENTER_Y+96
|
|
||||||
IconChoiceRoutineOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoiceRoutineOffCommand=linear,0.05;zoomx,0
|
|
||||||
#
|
|
||||||
IconChoicekb7X=SCREEN_CENTER_X
|
|
||||||
IconChoicekb7Y=SCREEN_CENTER_Y
|
|
||||||
IconChoicekb7OnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoicekb7OffCommand=linear,0.05;zoomx,0
|
|
||||||
#
|
|
||||||
IconChoice5KeysX=SCREEN_CENTER_X-160
|
|
||||||
IconChoice5KeysY=SCREEN_CENTER_Y-48
|
|
||||||
IconChoice5KeysOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoice5KeysOffCommand=linear,0.05;zoomx,0
|
|
||||||
#
|
|
||||||
IconChoice7KeysX=SCREEN_CENTER_X-160
|
|
||||||
IconChoice7KeysY=SCREEN_CENTER_Y+48
|
|
||||||
IconChoice7KeysOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoice7KeysOffCommand=linear,0.05;zoomx,0
|
|
||||||
#
|
|
||||||
IconChoice10KeysX=SCREEN_CENTER_X+160
|
|
||||||
IconChoice10KeysY=SCREEN_CENTER_Y-48
|
|
||||||
IconChoice10KeysOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoice10KeysOffCommand=linear,0.05;zoomx,0
|
|
||||||
#
|
|
||||||
IconChoice14KeysX=SCREEN_CENTER_X+160
|
|
||||||
IconChoice14KeysY=SCREEN_CENTER_Y+48
|
|
||||||
IconChoice14KeysOnCommand=zoom,0;bounceend,0.35;zoom,1
|
|
||||||
IconChoice14KeysOffCommand=linear,0.05;zoomx,0
|
|
||||||
|
|
||||||
[ScreenSelectPlayMode]
|
[ScreenSelectPlayMode]
|
||||||
PersistScreens="ScreenSelectPlayMode,ScreenSelectMusic"
|
PersistScreens="ScreenSelectPlayMode,ScreenSelectMusic"
|
||||||
|
|||||||
+2
-2
@@ -1300,9 +1300,9 @@ void Actor::QueueMessage( const RString& sMessageName )
|
|||||||
TI.m_sCommandName = "!" + sMessageName;
|
TI.m_sCommandName = "!" + sMessageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::AddCommand( const RString &sCmdName, apActorCommands apac )
|
void Actor::AddCommand( const RString &sCmdName, apActorCommands apac, bool warn )
|
||||||
{
|
{
|
||||||
if( HasCommand(sCmdName) )
|
if( HasCommand(sCmdName) && warn)
|
||||||
{
|
{
|
||||||
RString sWarning = GetLineage()+"'s command '"+sCmdName+"' defined twice";
|
RString sWarning = GetLineage()+"'s command '"+sCmdName+"' defined twice";
|
||||||
LuaHelpers::ReportScriptError(sWarning, "COMMAND_DEFINED_TWICE");
|
LuaHelpers::ReportScriptError(sWarning, "COMMAND_DEFINED_TWICE");
|
||||||
|
|||||||
+1
-1
@@ -577,7 +577,7 @@ public:
|
|||||||
virtual void PushContext( lua_State *L );
|
virtual void PushContext( lua_State *L );
|
||||||
|
|
||||||
// Named commands
|
// Named commands
|
||||||
void AddCommand( const RString &sCmdName, apActorCommands apac );
|
void AddCommand( const RString &sCmdName, apActorCommands apac, bool warn= true );
|
||||||
bool HasCommand( const RString &sCmdName ) const;
|
bool HasCommand( const RString &sCmdName ) const;
|
||||||
const apActorCommands *GetCommand( const RString &sCommandName ) const;
|
const apActorCommands *GetCommand( const RString &sCommandName ) const;
|
||||||
void PlayCommand( const RString &sCommandName ) { HandleMessage( Message(sCommandName) ); } // convenience
|
void PlayCommand( const RString &sCommandName ) { HandleMessage( Message(sCommandName) ); } // convenience
|
||||||
|
|||||||
+3
-3
@@ -3163,12 +3163,12 @@ static const Style g_Style_Kickbox_Arachnid_Versus=
|
|||||||
static const Style* g_apGame_Kickbox_Styles[] =
|
static const Style* g_apGame_Kickbox_Styles[] =
|
||||||
{
|
{
|
||||||
&g_Style_Kickbox_Human,
|
&g_Style_Kickbox_Human,
|
||||||
&g_Style_Kickbox_Human_Versus,
|
|
||||||
&g_Style_Kickbox_Quadarm,
|
&g_Style_Kickbox_Quadarm,
|
||||||
&g_Style_Kickbox_Quadarm_Versus,
|
|
||||||
&g_Style_Kickbox_Insect,
|
&g_Style_Kickbox_Insect,
|
||||||
&g_Style_Kickbox_Insect_Versus,
|
|
||||||
&g_Style_Kickbox_Arachnid,
|
&g_Style_Kickbox_Arachnid,
|
||||||
|
&g_Style_Kickbox_Human_Versus,
|
||||||
|
&g_Style_Kickbox_Quadarm_Versus,
|
||||||
|
&g_Style_Kickbox_Insect_Versus,
|
||||||
&g_Style_Kickbox_Arachnid_Versus,
|
&g_Style_Kickbox_Arachnid_Versus,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|||||||
+17
-28
@@ -998,7 +998,7 @@ void GameState::SetCompatibleStylesForPlayers()
|
|||||||
SetCurrentStyle(style, PLAYER_INVALID);
|
SetCurrentStyle(style, PLAYER_INVALID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if(GetCurrentStyle(PLAYER_INVALID) == NULL)
|
||||||
{
|
{
|
||||||
vector<StepsType> vst;
|
vector<StepsType> vst;
|
||||||
GAMEMAN->GetStepsTypesForGame(m_pCurGame, vst);
|
GAMEMAN->GetStepsTypesForGame(m_pCurGame, vst);
|
||||||
@@ -1009,37 +1009,26 @@ void GameState::SetCompatibleStylesForPlayers()
|
|||||||
}
|
}
|
||||||
if(!style_set)
|
if(!style_set)
|
||||||
{
|
{
|
||||||
if(GetCurrentGame()->m_PlayersHaveSeparateStyles)
|
FOREACH_EnabledPlayer(pn)
|
||||||
{
|
{
|
||||||
FOREACH_EnabledPlayer(pn)
|
StepsType st= StepsType_Invalid;
|
||||||
|
if(m_pCurSteps[pn] != NULL)
|
||||||
{
|
{
|
||||||
StepsType st= StepsType_Invalid;
|
st= m_pCurSteps[pn]->m_StepsType;
|
||||||
if(m_pCurSteps[pn] != NULL)
|
}
|
||||||
{
|
else if(m_pCurTrail[pn] != NULL)
|
||||||
st= m_pCurSteps[pn]->m_StepsType;
|
{
|
||||||
}
|
st= m_pCurTrail[pn]->m_StepsType;
|
||||||
else if(m_pCurTrail[pn] != NULL)
|
}
|
||||||
{
|
else
|
||||||
st= m_pCurTrail[pn]->m_StepsType;
|
{
|
||||||
}
|
vector<StepsType> vst;
|
||||||
else
|
GAMEMAN->GetStepsTypesForGame(m_pCurGame, vst);
|
||||||
{
|
st= vst[0];
|
||||||
vector<StepsType> vst;
|
|
||||||
GAMEMAN->GetStepsTypesForGame(m_pCurGame, vst);
|
|
||||||
st= vst[0];
|
|
||||||
}
|
|
||||||
const Style *style = GAMEMAN->GetFirstCompatibleStyle(
|
|
||||||
m_pCurGame, GetNumSidesJoined(), st);
|
|
||||||
SetCurrentStyle(style, pn);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vector<StepsType> vst;
|
|
||||||
GAMEMAN->GetStepsTypesForGame(m_pCurGame, vst);
|
|
||||||
const Style *style = GAMEMAN->GetFirstCompatibleStyle(
|
const Style *style = GAMEMAN->GetFirstCompatibleStyle(
|
||||||
m_pCurGame, GetNumSidesJoined(), vst[0]);
|
m_pCurGame, GetNumSidesJoined(), st);
|
||||||
SetCurrentStyle(style, PLAYER_INVALID);
|
SetCurrentStyle(style, pn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,46 @@ void ScreenSelect::Init()
|
|||||||
this->SubscribeToMessage( Message_PlayerJoined );
|
this->SubscribeToMessage( Message_PlayerJoined );
|
||||||
|
|
||||||
// Load choices
|
// Load choices
|
||||||
|
// Allow lua as an alternative to metrics.
|
||||||
|
RString choice_names= CHOICE_NAMES;
|
||||||
|
if(choice_names.Left(4) == "lua,")
|
||||||
|
{
|
||||||
|
RString command= choice_names.Right(choice_names.size()-4);
|
||||||
|
Lua* L= LUA->Get();
|
||||||
|
if(LuaHelpers::RunExpression(L, command, m_sName + "::ChoiceNames"))
|
||||||
|
{
|
||||||
|
if(!lua_istable(L, 1))
|
||||||
|
{
|
||||||
|
LuaHelpers::ReportScriptError(m_sName + "::ChoiceNames expression did not return a table of gamecommands.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t len= lua_objlen(L, 1);
|
||||||
|
for(size_t i= 1; i <= len; ++i)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, 1, i);
|
||||||
|
if(!lua_isstring(L, -1))
|
||||||
|
{
|
||||||
|
LuaHelpers::ReportScriptErrorFmt(m_sName + "::ChoiceNames element %zu is not a string.", i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RString com= SArg(-1);
|
||||||
|
GameCommand mc;
|
||||||
|
mc.ApplyCommitsScreens(false);
|
||||||
|
mc.m_sName = ssprintf("%zu", i);
|
||||||
|
Commands cmd= ParseCommands(com);
|
||||||
|
mc.Load(i, cmd);
|
||||||
|
m_aGameCommands.push_back(mc);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_settop(L, 0);
|
||||||
|
LUA->Release(L);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Instead of using NUM_CHOICES, use a comma-separated list of choices.
|
// Instead of using NUM_CHOICES, use a comma-separated list of choices.
|
||||||
// Each element in the list is a choice name. This level of indirection
|
// Each element in the list is a choice name. This level of indirection
|
||||||
|
|||||||
@@ -104,6 +104,68 @@ void ScreenSelectMaster::Init()
|
|||||||
FOREACH( PlayerNumber, vpns, p )
|
FOREACH( PlayerNumber, vpns, p )
|
||||||
m_vsprScroll[*p].resize( m_aGameCommands.size() );
|
m_vsprScroll[*p].resize( m_aGameCommands.size() );
|
||||||
|
|
||||||
|
vector<RageVector3> positions;
|
||||||
|
bool positions_set_by_lua= false;
|
||||||
|
if(THEME->HasMetric(m_sName, "IconChoicePosFunction"))
|
||||||
|
{
|
||||||
|
positions_set_by_lua= true;
|
||||||
|
LuaReference command= THEME->GetMetricR(m_sName, "IconChoicePosFunction");
|
||||||
|
if(command.GetLuaType() != LUA_TFUNCTION)
|
||||||
|
{
|
||||||
|
LuaHelpers::ReportScriptError(m_sName+"::IconChoicePosFunction must be a function.");
|
||||||
|
positions_set_by_lua= false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Lua* L= LUA->Get();
|
||||||
|
command.PushSelf(L);
|
||||||
|
lua_pushnumber(L, m_aGameCommands.size());
|
||||||
|
RString err= m_sName + "::IconChoicePosFunction: ";
|
||||||
|
if(!LuaHelpers::RunScriptOnStack(L, err, 1, 1, true))
|
||||||
|
{
|
||||||
|
positions_set_by_lua= false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
LuaHelpers::ReportScriptError(m_sName+"::IconChoicePosFunction did not return a table of positions.");
|
||||||
|
positions_set_by_lua= false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t poses= lua_objlen(L, -1);
|
||||||
|
for(size_t p= 1; p <= poses; ++p)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, -1, p);
|
||||||
|
RageVector3 pos(0.0f, 0.0f, 0.0f);
|
||||||
|
if(!lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
LuaHelpers::ReportScriptErrorFmt("Position %zu is not a table.", p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#define SET_POS_PART(i, part) \
|
||||||
|
lua_rawgeti(L, -1, i); \
|
||||||
|
pos.part= lua_tonumber(L, -1); \
|
||||||
|
lua_pop(L, 1);
|
||||||
|
// If part of the position is not provided, we want it to
|
||||||
|
// default to zero, which lua_tonumber does. -Kyz
|
||||||
|
SET_POS_PART(1, x);
|
||||||
|
SET_POS_PART(2, y);
|
||||||
|
SET_POS_PART(3, z);
|
||||||
|
#undef SET_POS_PART
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
positions.push_back(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_settop(L, 0);
|
||||||
|
LUA->Release(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for( unsigned c=0; c<m_aGameCommands.size(); c++ )
|
for( unsigned c=0; c<m_aGameCommands.size(); c++ )
|
||||||
{
|
{
|
||||||
GameCommand& mc = m_aGameCommands[c];
|
GameCommand& mc = m_aGameCommands[c];
|
||||||
@@ -122,7 +184,26 @@ void ScreenSelectMaster::Init()
|
|||||||
RString sName = "Icon" "Choice" + mc.m_sName;
|
RString sName = "Icon" "Choice" + mc.m_sName;
|
||||||
m_vsprIcon[c]->SetName( sName );
|
m_vsprIcon[c]->SetName( sName );
|
||||||
if( USE_ICON_METRICS )
|
if( USE_ICON_METRICS )
|
||||||
LOAD_ALL_COMMANDS_AND_SET_XY( m_vsprIcon[c] );
|
{
|
||||||
|
if(positions_set_by_lua)
|
||||||
|
{
|
||||||
|
LOAD_ALL_COMMANDS(m_vsprIcon[c]);
|
||||||
|
m_vsprIcon[c]->SetXY(positions[c].x, positions[c].y);
|
||||||
|
m_vsprIcon[c]->SetZ(positions[c].z);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOAD_ALL_COMMANDS_AND_SET_XY( m_vsprIcon[c] );
|
||||||
|
}
|
||||||
|
#define OPTIONAL_COMMAND(onoff) \
|
||||||
|
if(THEME->HasMetric(m_sName, "IconChoice" onoff "Command")) \
|
||||||
|
{ \
|
||||||
|
m_vsprIcon[c]->AddCommand(onoff, THEME->GetMetricA(m_sName, "IconChoice" onoff "Command"), false); \
|
||||||
|
}
|
||||||
|
OPTIONAL_COMMAND("On");
|
||||||
|
OPTIONAL_COMMAND("Off");
|
||||||
|
#undef OPTIONAL_COMMAND
|
||||||
|
}
|
||||||
this->AddChild( m_vsprIcon[c] );
|
this->AddChild( m_vsprIcon[c] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user