Added ScreenHeartEntry to default theme.

This commit is contained in:
Kyzentun
2014-09-12 15:07:46 -06:00
parent b20fe48bba
commit f87afa8a4b
8 changed files with 272 additions and 2 deletions
+22 -2
View File
@@ -182,8 +182,7 @@ Branch = {
GameplayScreen = function()
return IsRoutine() and "ScreenGameplayShared" or "ScreenGameplay"
end,
AfterGameplay = function()
-- pick an evaluation screen based on settings.
EvaluationScreen= function()
if IsNetSMOnline() then
return "ScreenNetEvaluation"
else
@@ -191,6 +190,27 @@ Branch = {
return "ScreenEvaluationNormal"
end
end,
AfterGameplay = function()
-- pick an evaluation screen based on settings.
if THEME:GetMetric("ScreenHeartEntry", "HeartEntryEnabled") then
local go_to_heart= false
for i, pn in ipairs(GAMESTATE:GetEnabledPlayers()) do
local profile= PROFILEMAN:GetProfile(pn)
if profile and profile:GetIgnoreStepCountCalories() then
go_to_heart= true
end
end
if go_to_heart then
return "ScreenHeartEntry"
end
return Branch.EvaluationScreen()
else
return Branch.EvaluationScreen()
end
end,
AfterHeartEntry= function()
return Branch.EvaluationScreen()
end,
AfterEvaluation = function()
if GAMESTATE:IsCourseMode() then
return "ScreenProfileSave"
+13
View File
@@ -3547,6 +3547,19 @@ Class="ScreenGameplayShared"
Fallback="ScreenGameplay"
PlayerType="PlayerShared"
[ScreenHeartEntry]
Class="ScreenWithMenuElements"
Fallback="ScreenWithMenuElements"
PrevScreen=Branch.AfterHeartEntry()
NextScreen=Branch.AfterHeartEntry()
HeartEntryEnabled=false
PlayMusic=false
ShowHeader=false
ShowFooter=false
ShowCreditDisplay=false
TimerSeconds=-1
TimerOnCommand=visible,false
[ScreenEvaluation]
Class="ScreenEvaluation"
Fallback="ScreenWithMenuElements"
@@ -0,0 +1,220 @@
-- The positions of the numbers on the numpad.
local numpad_poses= {
{-24, -24}, {0, -24}, {24, -24},
{-24, 0}, {0, 0}, {24, 0},
{-24, 24}, {0, 24}, {24, 24},
{-24, 48}, {0, 48}, {24, 48}}
-- Some special escape sequences are converted to special characters.
local done_text= "&start;"
local back_text= "←"
local numpad_nums= {7, 8, 9, 4, 5, 6, 1, 2, 3, 0, done_text, back_text}
if MonthOfYear() == 3 and DayOfMonth() == 1 then
for i= 1, #numpad_nums do
local a= math.random(1, #numpad_nums)
local b= math.random(1, #numpad_nums)
numpad_nums[a], numpad_nums[b]= numpad_nums[b], numpad_nums[a]
end
end
-- Each of these will be filled with an entry for each player that is
-- entering their heart rate.
-- This way, the actors are stored in convenient tables, so we don't have to go
-- through an inconvenient and inefficient chain of GetChild calls when we need
-- to change one of them.
local cursor_poses= {}
local cursor_quads= {}
local values= {}
local value_texts= {}
local done_status= {}
-- This creates the actor that will show the numpad, prompt, and value for a
-- player. The PlayerNumber is passed in so that it can add its parts to the
-- tables above.
local function entry_pad(name, x, y, pn)
local args= {
Name= name, InitCommand= cmd(xy, x, y),
-- The cursor actor. First in the frame so it will be behind the text.
Def.Quad{
Name= "cursor", InitCommand= function(self)
self:setsize(16, 24)
self:diffuse(PlayerDarkColor(pn))
cursor_quads[pn]= self
end
},
Def.BitmapText{
Name= "rate_label", Font= "Common Normal",
Text= THEME:GetString("ScreenHeartEntry", "Heart Rate"),
InitCommand= cmd(xy, 0, -72; diffuse, Color.White)
},
Def.BitmapText{
Name= "value", Font= "Common Normal", Text= "0",
InitCommand= function(self)
self:xy(0, -48)
self:diffuse(PlayerColor(pn))
value_texts[pn]= self
end
}
}
-- A loop is used to add each of the numbers on the numpad to shorten the
-- code and make it easier to add numbers later.
for i, num in ipairs(numpad_nums) do
args[#args+1]= Def.BitmapText{
Name= "num"..i, Font= "Common Normal", Text= num,
InitCommand= cmd(xy, numpad_poses[i][1], numpad_poses[i][2]; diffuse, Color.White)
}
end
return Def.ActorFrame(args)
end
-- A function to update the cursor position for a player.
local function update_cursor(pn)
local pos= numpad_poses[cursor_poses[pn]]
cursor_quads[pn]:stoptweening()
cursor_quads[pn]:linear(.1)
cursor_quads[pn]:xy(pos[1], pos[2])
end
local function pad_input(pn, button)
if button == "Start" then
local num= numpad_nums[cursor_poses[pn]]
local as_num= tonumber(num)
if as_num then
local new_value= (values[pn] * 10) + as_num
if new_value < 300 then
values[pn]= new_value
if new_value > 100 then
cursor_poses[pn]= 11
update_cursor(pn)
end
value_texts[pn]:settext(values[pn])
else
SOUND:PlayOnce(THEME:GetPathS("Common", "Invalid"))
end
return false
else
if num == done_text then
done_status[pn]= true
return true
elseif num == back_text then
values[pn]= math.floor(values[pn]/10)
value_texts[pn]:settext(values[pn])
return false
end
end
else
local adds= {
Left= {2, -1, -1},
Right= {1, 1, -2},
MenuLeft= {-1, -1, -1},
MenuRight= {1, 1, 1},
Up= {9, -3, -3, -3},
Down= {3, 3, 3, -9}
}
adds.MenuUp= adds.Up
adds.MenuDown= adds.Down
local lr_buttons= {
Left= true, Right= true, MenuLeft= true, MenuRight= true}
if adds[button] then
local index= 0
if lr_buttons[button] then
index= ((cursor_poses[pn] - 1) % 3) + 1
else
index= math.ceil(cursor_poses[pn] / 3)
end
local new_pos= cursor_poses[pn] + adds[button][index]
if new_pos < 1 then new_pos= #numpad_nums end
if new_pos > #numpad_nums then new_pos= 1 end
cursor_poses[pn]= new_pos
update_cursor(pn)
return false
end
end
return false
end
local function input(event)
local pn= event.PlayerNumber
Trace("input recieved")
if not pn then return end
Trace("has a pn")
if event.type == "InputEventType_Release" then return end
Trace("not a release")
if not cursor_poses[pn] then return end
Trace("has a cursor")
local done= pad_input(pn, event.button)
if done then
local all_done= true
for i, status in pairs(done_status) do
if not status then all_done= false break end
end
if all_done then
for pn, value in pairs(values) do
local profile= PROFILEMAN:GetProfile(pn)
if profile and profile:GetIgnoreStepCountCalories() then
local calories= profile:CalculateCaloriesFromHeartRate(
values[pn], GAMESTATE:GetLastGameplayDuration())
profile:AddCaloriesToDailyTotal(calories)
end
end
SOUND:PlayOnce(THEME:GetPathS("Common", "Start"))
SCREENMAN:GetTopScreen():StartTransitioningScreen("SM_GoToNextScreen")
end
end
end
local heart_xs= {
[PLAYER_1]= SCREEN_WIDTH * .25,
[PLAYER_2]= SCREEN_WIDTH * .75,
}
local timer_text
local function timer_update(self)
local time= math.floor((self:GetSecsIntoEffect() % 60) * 10) / 10
if time < 10 then
timer_text:settext(("0%.1f"):format(time))
else
timer_text:settext(("%.1f"):format(time))
end
end
local args= {
Def.ActorFrame{
Name= "timer",
InitCommand= function(self)
self:effectperiod(2^16)
timer_text= self:GetChild("timer_text")
self:SetUpdateFunction(timer_update)
end,
OnCommand= function(self)
SCREENMAN:GetTopScreen():AddInputCallback(input)
end,
Def.BitmapText{
Name= "timer_text", Font= "Common Normal", Text= "00.0",
InitCommand= cmd(xy, SCREEN_CENTER_X, SCREEN_CENTER_Y; diffuse, Color.White)
}
},
Def.BitmapText{
Name= "explanation", Font= "Common Normal",
Text= THEME:GetString("ScreenHeartEntry", "Enter Heart Rate"),
InitCommand= cmd(xy, SCREEN_CENTER_X, SCREEN_CENTER_Y-120; diffuse, Color.White)},
Def.BitmapText{
Name= "song_len_label", Font= "Common Normal",
Text= THEME:GetString("ScreenHeartEntry", "Song Length"),
InitCommand= cmd(xy, SCREEN_CENTER_X, SCREEN_CENTER_Y-72; diffuse, Color.White)},
Def.BitmapText{
Name= "song_len", Font= "Common Normal",
Text= SecondsToMMSS(GAMESTATE:GetLastGameplayDuration()),
InitCommand= cmd(xy, SCREEN_CENTER_X, SCREEN_CENTER_Y-48; diffuse, Color.White)},
}
for i, pn in ipairs(GAMESTATE:GetEnabledPlayers()) do
local profile= PROFILEMAN:GetProfile(pn)
if profile and profile:GetIgnoreStepCountCalories() then
cursor_poses[pn]= 5
values[pn]= 0
done_status[pn]= false
args[#args+1]= entry_pad(pn, heart_xs[pn], SCREEN_CENTER_Y, pn)
end
end
return Def.ActorFrame(args)
+5
View File
@@ -85,6 +85,11 @@ HelpText=
[ScreenGameplay]
HelpText=
[ScreenHeartEntry]
Enter Heart Rate=Enter Heart Rate
Song Length=Song Length
Heart Rate=Heart Rate
[ScreenEvaluation]
HelpText=&BACK; Exit &START; Move On &MENULEFT;+&MENURIGHT; or &SELECT; Snapshot
LifeDifficulty=Life Difficulty: %s
+3
View File
@@ -1628,6 +1628,9 @@ ActiveAttackListP2OffCommand=
[ScreenGameplayShared]
[ScreenHeartEntry]
HeartEntryEnabled=true
[ScreenEvaluation]
Class="ScreenEvaluation"
Fallback="ScreenWithMenuElements"
+2
View File
@@ -2406,6 +2406,7 @@ public:
p->m_Position.PushSelf(L);
return 1;
}
DEFINE_METHOD( GetLastGameplayDuration, m_DanceDuration )
DEFINE_METHOD( GetGameplayLeadIn, m_bGameplayLeadIn )
DEFINE_METHOD( GetCoins, m_iCoins )
DEFINE_METHOD( IsSideJoined, m_bSideIsJoined[Enum::Check<PlayerNumber>(L, 1)] )
@@ -2815,6 +2816,7 @@ public:
ADD_METHOD( GetSongFreeze );
ADD_METHOD( GetSongDelay );*/
ADD_METHOD( GetSongPosition );
ADD_METHOD( GetLastGameplayDuration );
ADD_METHOD( GetGameplayLeadIn );
ADD_METHOD( GetCoins );
ADD_METHOD( IsSideJoined );
+4
View File
@@ -267,6 +267,10 @@ public:
float m_fLastHasteUpdateMusicSeconds;
float m_fAccumulatedHasteSeconds;
// used by themes that support heart rate entry.
RageTimer m_DanceStartTime;
float m_DanceDuration;
// Random Attacks & Attack Mines
vector<RString> m_RandomAttacks;
+3
View File
@@ -2507,6 +2507,8 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
else
SOUND->PlayOnceFromAnnouncer( "gameplay here we go normal" );
GAMESTATE->m_DanceStartTime.Touch();
m_Go.StartTransitioning( SM_None );
GAMESTATE->m_bGameplayLeadIn.Set( false );
m_DancingState = STATE_DANCING; // STATE CHANGE! Now the user is allowed to press Back
@@ -2556,6 +2558,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
}
else if( SM == SM_LeaveGameplay )
{
GAMESTATE->m_DanceDuration= GAMESTATE->m_DanceStartTime.Ago();
// update dancing characters for win / lose
DancingCharacters *pDancers = NULL;
if( m_pSongBackground )