Merge
This commit is contained in:
@@ -8,6 +8,32 @@ ________________________________________________________________________________
|
||||
StepMania 5.0 ???? ?? | 20120???
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
2012/07/06
|
||||
----------
|
||||
* [ScoreDisplayRave] Add FrameBase and FrameOver to the metrics. [AJ]
|
||||
|
||||
2012/07/05
|
||||
----------
|
||||
* [ScreenRanking] Added "NextPage" command. "SwitchPage" command is
|
||||
now "SwitchedPage". [AJ]
|
||||
* [ScreenRanking] Don't clobber alpha values when applying colors in SetPage. [AJ]
|
||||
|
||||
2012/07/03
|
||||
----------
|
||||
* [ScreenHowToPlay] Actually shows notes again. [AJ]
|
||||
* [ScreenGameplay] When ShowLifeMeterForDisabledPlayers is true, don't fill up
|
||||
life in the meter for the disabled player. (LifeMeterBar only) [AJ]
|
||||
|
||||
2012/07/02
|
||||
----------
|
||||
* [ScreenHowToPlay] Run InitCommand on Characters if enabled. [AJ]
|
||||
* [RageUtil] Add detection of ".hg" to StripCvsAndSvn. [AJ]
|
||||
|
||||
2012/06/27
|
||||
----------
|
||||
* [SongManager] Ending a group's name in PreferredSongs with "/*" will now load
|
||||
all songs from that group automatically. [AJ]
|
||||
|
||||
2012/06/21
|
||||
----------
|
||||
* [ProfileManager] Added GetPlayerName(pn) Lua binding. [AJ]
|
||||
|
||||
@@ -1732,6 +1732,8 @@ Edit/Share=Edycja
|
||||
Exit=Wyjście
|
||||
Game Start=Start
|
||||
Jukebox=Odtwarzacz
|
||||
Report Bug=Zgłoś błąd!
|
||||
Chat on IRC=Dyskutuj na IRC!
|
||||
Select Game=Wybór trybu gry
|
||||
Theme=Motyw graficzny
|
||||
Credits=Autorzy
|
||||
|
||||
@@ -1,173 +1,173 @@
|
||||
#TITLE:Sync;
|
||||
#SUBTITLE:;
|
||||
#ARTIST:Unknown artist;
|
||||
#TITLETRANSLIT:;
|
||||
#SUBTITLETRANSLIT:;
|
||||
#ARTISTTRANSLIT:;
|
||||
#GENRE:;
|
||||
#CREDIT:;
|
||||
#BANNER:;
|
||||
#BACKGROUND:;
|
||||
#LYRICSPATH:;
|
||||
#CDTITLE:;
|
||||
#MUSIC:_sync music.ogg;
|
||||
#OFFSET:-0.012;
|
||||
#SAMPLESTART:0.000;
|
||||
#SAMPLELENGTH:12.000;
|
||||
#SELECTABLE:YES;
|
||||
#BPMS:0.000=132.000;
|
||||
#STOPS:;
|
||||
#BGCHANGES:;
|
||||
#KEYSOUNDS:;
|
||||
|
||||
#NOTEDATA:;
|
||||
#STEPSTYPE:dance-single:;
|
||||
#DESCRIPTION:blank;
|
||||
#DIFFICULTY:Beginner;
|
||||
#METER:1;
|
||||
#RADARVALUES:0.302,0.205,0.000,0.000,0.000;
|
||||
#BPMS:0.000=132.000;
|
||||
#OFFSET:-0.012;
|
||||
#NOTES:
|
||||
// measure 1
|
||||
0000
|
||||
, // measure 2
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 3
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 4
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 5
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 6
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 7
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 8
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
;
|
||||
|
||||
#NOTEDATA:;
|
||||
#STEPSTYPE:pump-single;
|
||||
#DESCRIPTION:blank;
|
||||
#DIFFICULTY:Beginner;
|
||||
#METER:1;
|
||||
#RADARVALUES:0.302,0.205,0.000,0.000,0.000;
|
||||
#BPMS:0.000=132.000;
|
||||
#OFFSET:-0.012;
|
||||
#NOTES:
|
||||
// measure 1
|
||||
00000
|
||||
, // measure 2
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 3
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 4
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 5
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 6
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 7
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 8
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
;
|
||||
#TITLE:Sync;
|
||||
#SUBTITLE:;
|
||||
#ARTIST:Unknown artist;
|
||||
#TITLETRANSLIT:;
|
||||
#SUBTITLETRANSLIT:;
|
||||
#ARTISTTRANSLIT:;
|
||||
#GENRE:;
|
||||
#CREDIT:;
|
||||
#BANNER:;
|
||||
#BACKGROUND:;
|
||||
#LYRICSPATH:;
|
||||
#CDTITLE:;
|
||||
#MUSIC:_sync music.ogg;
|
||||
#OFFSET:-0.025;
|
||||
#SAMPLESTART:0.000;
|
||||
#SAMPLELENGTH:12.000;
|
||||
#SELECTABLE:YES;
|
||||
#BPMS:0.000=132.027;
|
||||
#STOPS:;
|
||||
#BGCHANGES:;
|
||||
#KEYSOUNDS:;
|
||||
|
||||
#NOTEDATA:;
|
||||
#STEPSTYPE:dance-single;
|
||||
#DESCRIPTION:blank;
|
||||
#DIFFICULTY:Beginner;
|
||||
#METER:1;
|
||||
#RADARVALUES:0.302,0.205,0.000,0.000,0.000;
|
||||
#BPMS:0.000=132.027;
|
||||
#OFFSET:-0.025;
|
||||
#NOTES:
|
||||
// measure 1
|
||||
0000
|
||||
, // measure 2
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 3
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 4
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 5
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 6
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 7
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
, // measure 8
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
1000
|
||||
0001
|
||||
;
|
||||
|
||||
#NOTEDATA:;
|
||||
#STEPSTYPE:pump-single;
|
||||
#DESCRIPTION:blank;
|
||||
#DIFFICULTY:Beginner;
|
||||
#METER:1;
|
||||
#RADARVALUES:0.302,0.205,0.000,0.000,0.000;
|
||||
#BPMS:0.000=132.027;
|
||||
#OFFSET:-0.025;
|
||||
#NOTES:
|
||||
// measure 1
|
||||
00000
|
||||
, // measure 2
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 3
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 4
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 5
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 6
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 7
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
, // measure 8
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
10000
|
||||
00001
|
||||
;
|
||||
|
||||
@@ -1,349 +1,350 @@
|
||||
-- sm-ssc fallback theme | script ring 03 | Gameplay.lua
|
||||
-- [en] This file is used to store settings that should be different in each
|
||||
-- game mode.
|
||||
|
||||
-- shakesoda calls this pump.lua
|
||||
local function CurGameName()
|
||||
return GAMESTATE:GetCurrentGame():GetName()
|
||||
end
|
||||
|
||||
-- Check the active game mode against a string. Cut down typing this in metrics.
|
||||
function IsGame(str) return CurGameName() == str end
|
||||
|
||||
-- GetExtraColorThreshold()
|
||||
-- [en] returns the difficulty threshold in meter
|
||||
-- for songs that should be counted as boss songs.
|
||||
function GetExtraColorThreshold()
|
||||
local Modes = {
|
||||
dance = 10,
|
||||
pump = 21,
|
||||
beat = 12,
|
||||
kb7 = 10,
|
||||
para = 10,
|
||||
techno = 10,
|
||||
lights = 10, -- lights shouldn't be playable
|
||||
}
|
||||
return Modes[CurGameName()]
|
||||
end
|
||||
|
||||
-- AllowOptionsMenu()
|
||||
-- [en] returns if you are able to select options
|
||||
-- on ScreenSelectMusic.
|
||||
function AllowOptionsMenu()
|
||||
if GAMESTATE:IsAnExtraStage() then
|
||||
return false
|
||||
elseif GAMESTATE:GetPlayMode() == "PlayMode_Oni" then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- GameCompatibleModes:
|
||||
-- [en] returns possible modes for ScreenSelectPlayMode
|
||||
function GameCompatibleModes()
|
||||
local Modes = {
|
||||
dance = "Single,Double,Solo,Versus,Couple",
|
||||
pump = "Single,Double,HalfDouble,Versus,Couple,Routine",
|
||||
beat = "5Keys,7Keys,10Keys,14Keys,Versus5,Versus7",
|
||||
kb7 = "KB7",
|
||||
para = "Single",
|
||||
-- todo: add versus modes for technomotion
|
||||
techno = "Single4,Single5,Single8,Double4,Double5,Double8",
|
||||
lights = "Single" -- lights shouldn't be playable
|
||||
}
|
||||
return Modes[CurGameName()]
|
||||
end
|
||||
|
||||
function SelectProfileKeys()
|
||||
local sGame = CurGameName()
|
||||
if sGame == "pump" then
|
||||
return "Up,Down,Start,Back,Center,DownLeft,DownRight"
|
||||
elseif sGame == "dance" then
|
||||
return "Up,Down,Start,Back,Up2,Down2"
|
||||
else
|
||||
return "Up,Down,Start,Back"
|
||||
end
|
||||
end
|
||||
|
||||
-- ScoreKeeperClass:
|
||||
-- [en] Determines the correct ScoreKeeper class to use.
|
||||
function ScoreKeeperClass()
|
||||
-- rave scorekeeper
|
||||
if GAMESTATE:GetPlayMode() == 'PlayMode_Rave' then return "ScoreKeeperRave" end
|
||||
if GAMESTATE:GetCurrentStyle() then
|
||||
local styleType = GAMESTATE:GetCurrentStyle():GetStyleType()
|
||||
if styleType == 'StyleType_TwoPlayersSharedSides' then return "ScoreKeeperShared" end
|
||||
end
|
||||
return "ScoreKeeperNormal"
|
||||
end
|
||||
|
||||
-- ComboContinue:
|
||||
-- [en]
|
||||
function ComboContinue()
|
||||
local Continue = {
|
||||
dance = GAMESTATE:GetPlayMode() == "PlayMode_Oni" and "TapNoteScore_W2" or "TapNoteScore_W3",
|
||||
pump = "TapNoteScore_W3",
|
||||
beat = "TapNoteScore_W3",
|
||||
kb7 = "TapNoteScore_W3",
|
||||
para = "TapNoteScore_W4"
|
||||
}
|
||||
return Continue[CurGameName()]
|
||||
end
|
||||
|
||||
function ComboMaintain()
|
||||
local Maintain = {
|
||||
dance = "TapNoteScore_W3",
|
||||
pump = "TapNoteScore_W4",
|
||||
beat = "TapNoteScore_W3",
|
||||
kb7 = "TapNoteScore_W3",
|
||||
para = "TapNoteScore_W4"
|
||||
}
|
||||
return Maintain[CurGameName()]
|
||||
end
|
||||
|
||||
function ComboPerRow()
|
||||
sGame = CurGameName()
|
||||
if sGame == "pump" then
|
||||
return true
|
||||
elseif GAMESTATE:GetPlayMode() == "PlayMode_Oni" then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function EvalUsesCheckpointsWithJudgments()
|
||||
return (CurGameName() == "pump") and true or false
|
||||
end
|
||||
|
||||
local ComboThresholds = {
|
||||
dance = { Hit = 2, Miss = 2, Fail = -1 },
|
||||
pump = { Hit = 4, Miss = 4, Fail = 51 },
|
||||
beat = { Hit = 1, Miss = 0, Fail = -1 },
|
||||
kb7 = { Hit = 1, Miss = 0, Fail = -1 },
|
||||
para = { Hit = 2, Miss = 0, Fail = -1 },
|
||||
-------------------------------------------
|
||||
default = { Hit = 2, Miss = 2, Fail = -1 }
|
||||
}
|
||||
|
||||
function HitCombo()
|
||||
if ComboThresholds[CurGameName()] then
|
||||
return ComboThresholds[CurGameName()].Hit
|
||||
end
|
||||
return ComboThresholds["default"].Hit
|
||||
end
|
||||
|
||||
function MissCombo()
|
||||
if ComboThresholds[CurGameName()] then
|
||||
return ComboThresholds[CurGameName()].Miss
|
||||
end
|
||||
return ComboThresholds["default"].Miss
|
||||
end
|
||||
|
||||
-- FailCombo:
|
||||
-- [en] The combo that causes game failure.
|
||||
function FailCombo()
|
||||
-- ITG (dance) uses 30. Pump Pro uses 30, real Pump uses 51
|
||||
if ComboThresholds[CurGameName()] then
|
||||
return ComboThresholds[CurGameName()].Fail
|
||||
end
|
||||
return ComboThresholds["default"].Fail
|
||||
end
|
||||
|
||||
local RoutineSkins = {
|
||||
dance = { P1 = "midi-routine-p1", P2 = "midi-routine-p2" },
|
||||
pump = { P1 = "cmd-routine-p1", P2 = "cmd-routine-p2" },
|
||||
kb7 = { P1 = "default", P2 = "retrobar" },
|
||||
-------------------------------------------------------------
|
||||
default = { P1 = "default", P2 = "default" }
|
||||
}
|
||||
|
||||
function RoutineSkinP1()
|
||||
if RoutineSkins[CurGameName()] then
|
||||
return RoutineSkins[CurGameName()].P1
|
||||
end
|
||||
return RoutineSkins["default"].P1
|
||||
end
|
||||
|
||||
function RoutineSkinP2()
|
||||
if RoutineSkins[CurGameName()] then
|
||||
return RoutineSkins[CurGameName()].P2
|
||||
end
|
||||
return RoutineSkins["default"].P2
|
||||
end
|
||||
|
||||
-- todo: use tables for some of these -aj
|
||||
function HoldTiming()
|
||||
return IsGame("pump") and 0 or PREFSMAN:GetPreference("TimingWindowSecondsHold")
|
||||
end
|
||||
|
||||
function ShowHoldJudgments()
|
||||
return not IsGame("pump")
|
||||
end
|
||||
|
||||
local CodeDetectorCodes = {
|
||||
-- steps
|
||||
PrevSteps1 = {
|
||||
default = "",
|
||||
dance = "Up,Up",
|
||||
pump = "+UpLeft",
|
||||
},
|
||||
PrevSteps2 = {
|
||||
default = "MenuUp,MenuUp",
|
||||
dance = "MenuUp,MenuUp",
|
||||
pump = "",
|
||||
},
|
||||
NextSteps1 = {
|
||||
default = "",
|
||||
dance = "Down,Down",
|
||||
pump = "+UpRight",
|
||||
},
|
||||
NextSteps2 = {
|
||||
default = "MenuDown,MenuDown",
|
||||
dance = "MenuDown,MenuDown",
|
||||
pump = "",
|
||||
},
|
||||
-- group
|
||||
NextGroup = {
|
||||
default = "",
|
||||
dance = "MenuUp,MenuRight,MenuRight",
|
||||
pump = "",
|
||||
},
|
||||
PrevGroup = {
|
||||
default = "",
|
||||
dance = "MenuUp,MenuDown,MenuUp,MenuDown",
|
||||
pump = "",
|
||||
},
|
||||
CloseCurrentFolder = {
|
||||
default = "MenuUp-MenuDown",
|
||||
},
|
||||
-- sorts
|
||||
NextSort1 = {
|
||||
default = "@MenuLeft-@MenuRight-Start",
|
||||
dance = "@MenuLeft-@MenuRight-Start",
|
||||
pump = "@MenuLeft-@MenuRight-Start",
|
||||
},
|
||||
NextSort2 = {
|
||||
default = "MenuLeft-MenuRight",
|
||||
dance = "MenuLeft-MenuRight",
|
||||
pump = "MenuLeft-MenuRight",
|
||||
},
|
||||
NextSort3 = {
|
||||
default = "",
|
||||
dance = "@Left-@Right-Start",
|
||||
pump = "@DownLeft-@DownRight-Start",
|
||||
},
|
||||
NextSort4 = {
|
||||
default = "",
|
||||
dance = "Left-Right",
|
||||
pump = "DownLeft-DownRight",
|
||||
},
|
||||
-- modemenu
|
||||
ModeMenu1 = {
|
||||
default = "",
|
||||
dance = "Up,Down,Up,Down",
|
||||
},
|
||||
ModeMenu2 = {
|
||||
default = "MenuUp,MenuDown,MenuUp,MenuDown",
|
||||
},
|
||||
-- Evaluation:
|
||||
SaveScreenshot1 = {
|
||||
default = "MenuLeft-MenuRight",
|
||||
},
|
||||
SaveScreenshot2 = {
|
||||
default = "Select",
|
||||
},
|
||||
-- modifiers section
|
||||
CancelAll = {
|
||||
default = "",
|
||||
dance = "Left,Right,Left,Right,Left,Right,Left,Right",
|
||||
},
|
||||
--- specific modifiers
|
||||
Mirror = {
|
||||
default = "",
|
||||
dance = "Up,Left,Right,Left,Right",
|
||||
pump = "DownRight,DownLeft,UpRight,UpLeft,DownRight,DownLeft,UpRight,UpLeft,Center",
|
||||
},
|
||||
Left = {
|
||||
default = "",
|
||||
dance = "Up,Down,Right,Left",
|
||||
},
|
||||
Right = {
|
||||
default = "",
|
||||
dance = "Up,Down,Left,Right",
|
||||
},
|
||||
Shuffle = {
|
||||
default = "",
|
||||
dance = "Down,Up,Down,Up",
|
||||
pump = "UpLeft,UpRight,UpLeft,UpRight,DownLeft,DownRight,DownLeft,DownRight,Center", -- random
|
||||
},
|
||||
SuperShuffle = {
|
||||
default = "",
|
||||
dance = "Down,Up,Left,Right",
|
||||
pump = "UpLeft,UpRight,DownLeft,DownRight,UpLeft,UpRight,DownLeft,DownRight,Center"
|
||||
},
|
||||
Reverse = {
|
||||
default = "",
|
||||
dance = "Down,Left,Right,Left,Right",
|
||||
pump = "UpLeft,DownLeft,UpRight,DownRight,UpLeft,DownLeft,UpRight,DownRight,DownRight", -- drop
|
||||
},
|
||||
HoldNotes = {
|
||||
default = "",
|
||||
dance = "Right,Left,Down,Up",
|
||||
},
|
||||
Mines = {
|
||||
default = "",
|
||||
},
|
||||
Dark = {
|
||||
default = "",
|
||||
},
|
||||
Hidden = {
|
||||
default = "",
|
||||
pump = "UpLeft,UpRight,DownLeft,DownRight,Center", -- vanish
|
||||
},
|
||||
RandomVanish = {
|
||||
default = "",
|
||||
},
|
||||
-- boost (accel), brake (decel), stealth (nonstep)
|
||||
--- next/prev modifiers
|
||||
NextTransform = {
|
||||
default = "",
|
||||
},
|
||||
NextScrollSpeed = {
|
||||
default = "",
|
||||
dance = "Up,Left,Down,Left,Up",
|
||||
pump = "UpLeft,UpRight,UpLeft,UpRight,Center",
|
||||
},
|
||||
PreviousScrollSpeed = {
|
||||
default = "",
|
||||
dance = "Down,Right,Up,Right,Down",
|
||||
pump = "UpRight,UpLeft,UpRight,UpLeft,Center",
|
||||
},
|
||||
NextAccel = {
|
||||
default = "",
|
||||
dance = "Left,Right,Down,Up",
|
||||
},
|
||||
NextEffect = {
|
||||
default = "",
|
||||
dance = "Left,Down,Right",
|
||||
},
|
||||
NextAppearance = {
|
||||
default = "",
|
||||
dance = "Left,Up,Right",
|
||||
},
|
||||
NextTurn = {
|
||||
default = "",
|
||||
},
|
||||
-- cancel all in player options
|
||||
CancelAllPlayerOptions = {
|
||||
default = "",
|
||||
dance = "Left,Right,Left,Right,Left,Right",
|
||||
},
|
||||
};
|
||||
|
||||
function GetCodeForGame(codeName)
|
||||
local gameName = string.lower(CurGameName())
|
||||
local inputCode = CodeDetectorCodes[codeName]
|
||||
return inputCode[gameName] or inputCode["default"]
|
||||
end
|
||||
-- sm-ssc fallback theme | script ring 03 | Gameplay.lua
|
||||
-- [en] This file is used to store settings that should be different in each
|
||||
-- game mode.
|
||||
|
||||
-- shakesoda calls this pump.lua
|
||||
local function CurGameName()
|
||||
return GAMESTATE:GetCurrentGame():GetName()
|
||||
end
|
||||
|
||||
-- Check the active game mode against a string. Cut down typing this in metrics.
|
||||
function IsGame(str) return CurGameName() == str end
|
||||
|
||||
-- GetExtraColorThreshold()
|
||||
-- [en] returns the difficulty threshold in meter
|
||||
-- for songs that should be counted as boss songs.
|
||||
function GetExtraColorThreshold()
|
||||
local Modes = {
|
||||
dance = 10,
|
||||
pump = 21,
|
||||
beat = 12,
|
||||
kb7 = 10,
|
||||
para = 10,
|
||||
techno = 10,
|
||||
lights = 10, -- lights shouldn't be playable
|
||||
}
|
||||
return Modes[CurGameName()]
|
||||
end
|
||||
|
||||
-- AllowOptionsMenu()
|
||||
-- [en] returns if you are able to select options
|
||||
-- on ScreenSelectMusic.
|
||||
function AllowOptionsMenu()
|
||||
if GAMESTATE:IsAnExtraStage() then
|
||||
return false
|
||||
elseif GAMESTATE:GetPlayMode() == "PlayMode_Oni" then
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- GameCompatibleModes:
|
||||
-- [en] returns possible modes for ScreenSelectPlayMode
|
||||
function GameCompatibleModes()
|
||||
local Modes = {
|
||||
dance = "Single,Double,Solo,Versus,Couple",
|
||||
pump = "Single,Double,HalfDouble,Versus,Couple,Routine",
|
||||
beat = "5Keys,7Keys,10Keys,14Keys,Versus5,Versus7",
|
||||
kb7 = "KB7",
|
||||
para = "Single",
|
||||
-- todo: add versus modes for technomotion
|
||||
techno = "Single4,Single5,Single8,Double4,Double5,Double8",
|
||||
lights = "Single" -- lights shouldn't be playable
|
||||
}
|
||||
return Modes[CurGameName()]
|
||||
end
|
||||
|
||||
function SelectProfileKeys()
|
||||
local sGame = CurGameName()
|
||||
if sGame == "pump" then
|
||||
return "Up,Down,Start,Back,Center,DownLeft,DownRight"
|
||||
elseif sGame == "dance" then
|
||||
return "Up,Down,Start,Back,Up2,Down2"
|
||||
else
|
||||
return "Up,Down,Start,Back"
|
||||
end
|
||||
end
|
||||
|
||||
-- ScoreKeeperClass:
|
||||
-- [en] Determines the correct ScoreKeeper class to use.
|
||||
function ScoreKeeperClass()
|
||||
-- rave scorekeeper
|
||||
if GAMESTATE:GetPlayMode() == 'PlayMode_Rave' then return "ScoreKeeperRave" end
|
||||
if GAMESTATE:GetCurrentStyle() then
|
||||
local styleType = GAMESTATE:GetCurrentStyle():GetStyleType()
|
||||
if styleType == 'StyleType_TwoPlayersSharedSides' then return "ScoreKeeperShared" end
|
||||
end
|
||||
return "ScoreKeeperNormal"
|
||||
end
|
||||
|
||||
-- ComboContinue:
|
||||
-- [en]
|
||||
function ComboContinue()
|
||||
local Continue = {
|
||||
dance = GAMESTATE:GetPlayMode() == "PlayMode_Oni" and "TapNoteScore_W2" or "TapNoteScore_W3",
|
||||
pump = "TapNoteScore_W3",
|
||||
beat = "TapNoteScore_W3",
|
||||
kb7 = "TapNoteScore_W3",
|
||||
para = "TapNoteScore_W4"
|
||||
}
|
||||
return Continue[CurGameName()]
|
||||
end
|
||||
|
||||
function ComboMaintain()
|
||||
local Maintain = {
|
||||
dance = "TapNoteScore_W3",
|
||||
pump = "TapNoteScore_W4",
|
||||
beat = "TapNoteScore_W3",
|
||||
kb7 = "TapNoteScore_W3",
|
||||
para = "TapNoteScore_W4"
|
||||
}
|
||||
return Maintain[CurGameName()]
|
||||
end
|
||||
|
||||
function ComboPerRow()
|
||||
sGame = CurGameName()
|
||||
if sGame == "pump" then
|
||||
return true
|
||||
elseif GAMESTATE:GetPlayMode() == "PlayMode_Oni" then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function EvalUsesCheckpointsWithJudgments()
|
||||
return (CurGameName() == "pump") and true or false
|
||||
end
|
||||
|
||||
local ComboThresholds = {
|
||||
dance = { Hit = 2, Miss = 2, Fail = -1 },
|
||||
pump = { Hit = 4, Miss = 4, Fail = 51 },
|
||||
beat = { Hit = 1, Miss = 0, Fail = -1 },
|
||||
kb7 = { Hit = 1, Miss = 0, Fail = -1 },
|
||||
para = { Hit = 2, Miss = 0, Fail = -1 },
|
||||
maniax = { Hit = 5, Miss = 0, Fail = -1 },
|
||||
-------------------------------------------
|
||||
default = { Hit = 2, Miss = 2, Fail = -1 }
|
||||
}
|
||||
|
||||
function HitCombo()
|
||||
if ComboThresholds[CurGameName()] then
|
||||
return ComboThresholds[CurGameName()].Hit
|
||||
end
|
||||
return ComboThresholds["default"].Hit
|
||||
end
|
||||
|
||||
function MissCombo()
|
||||
if ComboThresholds[CurGameName()] then
|
||||
return ComboThresholds[CurGameName()].Miss
|
||||
end
|
||||
return ComboThresholds["default"].Miss
|
||||
end
|
||||
|
||||
-- FailCombo:
|
||||
-- [en] The combo that causes game failure.
|
||||
function FailCombo()
|
||||
-- ITG (dance) uses 30. Pump Pro uses 30, real Pump uses 51
|
||||
if ComboThresholds[CurGameName()] then
|
||||
return ComboThresholds[CurGameName()].Fail
|
||||
end
|
||||
return ComboThresholds["default"].Fail
|
||||
end
|
||||
|
||||
local RoutineSkins = {
|
||||
dance = { P1 = "midi-routine-p1", P2 = "midi-routine-p2" },
|
||||
pump = { P1 = "cmd-routine-p1", P2 = "cmd-routine-p2" },
|
||||
kb7 = { P1 = "default", P2 = "retrobar" },
|
||||
-------------------------------------------------------------
|
||||
default = { P1 = "default", P2 = "default" }
|
||||
}
|
||||
|
||||
function RoutineSkinP1()
|
||||
if RoutineSkins[CurGameName()] then
|
||||
return RoutineSkins[CurGameName()].P1
|
||||
end
|
||||
return RoutineSkins["default"].P1
|
||||
end
|
||||
|
||||
function RoutineSkinP2()
|
||||
if RoutineSkins[CurGameName()] then
|
||||
return RoutineSkins[CurGameName()].P2
|
||||
end
|
||||
return RoutineSkins["default"].P2
|
||||
end
|
||||
|
||||
-- todo: use tables for some of these -aj
|
||||
function HoldTiming()
|
||||
return IsGame("pump") and 0 or PREFSMAN:GetPreference("TimingWindowSecondsHold")
|
||||
end
|
||||
|
||||
function ShowHoldJudgments()
|
||||
return not IsGame("pump")
|
||||
end
|
||||
|
||||
local CodeDetectorCodes = {
|
||||
-- steps
|
||||
PrevSteps1 = {
|
||||
default = "",
|
||||
dance = "Up,Up",
|
||||
pump = "+UpLeft",
|
||||
},
|
||||
PrevSteps2 = {
|
||||
default = "MenuUp,MenuUp",
|
||||
dance = "MenuUp,MenuUp",
|
||||
pump = "",
|
||||
},
|
||||
NextSteps1 = {
|
||||
default = "",
|
||||
dance = "Down,Down",
|
||||
pump = "+UpRight",
|
||||
},
|
||||
NextSteps2 = {
|
||||
default = "MenuDown,MenuDown",
|
||||
dance = "MenuDown,MenuDown",
|
||||
pump = "",
|
||||
},
|
||||
-- group
|
||||
NextGroup = {
|
||||
default = "",
|
||||
dance = "MenuUp,MenuRight,MenuRight",
|
||||
pump = "",
|
||||
},
|
||||
PrevGroup = {
|
||||
default = "",
|
||||
dance = "MenuUp,MenuDown,MenuUp,MenuDown",
|
||||
pump = "",
|
||||
},
|
||||
CloseCurrentFolder = {
|
||||
default = "MenuUp-MenuDown",
|
||||
},
|
||||
-- sorts
|
||||
NextSort1 = {
|
||||
default = "@MenuLeft-@MenuRight-Start",
|
||||
dance = "@MenuLeft-@MenuRight-Start",
|
||||
pump = "@MenuLeft-@MenuRight-Start",
|
||||
},
|
||||
NextSort2 = {
|
||||
default = "MenuLeft-MenuRight",
|
||||
dance = "MenuLeft-MenuRight",
|
||||
pump = "MenuLeft-MenuRight",
|
||||
},
|
||||
NextSort3 = {
|
||||
default = "",
|
||||
dance = "@Left-@Right-Start",
|
||||
pump = "@DownLeft-@DownRight-Start",
|
||||
},
|
||||
NextSort4 = {
|
||||
default = "",
|
||||
dance = "Left-Right",
|
||||
pump = "DownLeft-DownRight",
|
||||
},
|
||||
-- modemenu
|
||||
ModeMenu1 = {
|
||||
default = "",
|
||||
dance = "Up,Down,Up,Down",
|
||||
},
|
||||
ModeMenu2 = {
|
||||
default = "MenuUp,MenuDown,MenuUp,MenuDown",
|
||||
},
|
||||
-- Evaluation:
|
||||
SaveScreenshot1 = {
|
||||
default = "MenuLeft-MenuRight",
|
||||
},
|
||||
SaveScreenshot2 = {
|
||||
default = "Select",
|
||||
},
|
||||
-- modifiers section
|
||||
CancelAll = {
|
||||
default = "",
|
||||
dance = "Left,Right,Left,Right,Left,Right,Left,Right",
|
||||
},
|
||||
--- specific modifiers
|
||||
Mirror = {
|
||||
default = "",
|
||||
dance = "Up,Left,Right,Left,Right",
|
||||
pump = "DownRight,DownLeft,UpRight,UpLeft,DownRight,DownLeft,UpRight,UpLeft,Center",
|
||||
},
|
||||
Left = {
|
||||
default = "",
|
||||
dance = "Up,Down,Right,Left",
|
||||
},
|
||||
Right = {
|
||||
default = "",
|
||||
dance = "Up,Down,Left,Right",
|
||||
},
|
||||
Shuffle = {
|
||||
default = "",
|
||||
dance = "Down,Up,Down,Up",
|
||||
pump = "UpLeft,UpRight,UpLeft,UpRight,DownLeft,DownRight,DownLeft,DownRight,Center", -- random
|
||||
},
|
||||
SuperShuffle = {
|
||||
default = "",
|
||||
dance = "Down,Up,Left,Right",
|
||||
pump = "UpLeft,UpRight,DownLeft,DownRight,UpLeft,UpRight,DownLeft,DownRight,Center"
|
||||
},
|
||||
Reverse = {
|
||||
default = "",
|
||||
dance = "Down,Left,Right,Left,Right",
|
||||
pump = "UpLeft,DownLeft,UpRight,DownRight,UpLeft,DownLeft,UpRight,DownRight,DownRight", -- drop
|
||||
},
|
||||
HoldNotes = {
|
||||
default = "",
|
||||
dance = "Right,Left,Down,Up",
|
||||
},
|
||||
Mines = {
|
||||
default = "",
|
||||
},
|
||||
Dark = {
|
||||
default = "",
|
||||
},
|
||||
Hidden = {
|
||||
default = "",
|
||||
pump = "UpLeft,UpRight,DownLeft,DownRight,Center", -- vanish
|
||||
},
|
||||
RandomVanish = {
|
||||
default = "",
|
||||
},
|
||||
-- boost (accel), brake (decel), stealth (nonstep)
|
||||
--- next/prev modifiers
|
||||
NextTransform = {
|
||||
default = "",
|
||||
},
|
||||
NextScrollSpeed = {
|
||||
default = "",
|
||||
dance = "Up,Left,Down,Left,Up",
|
||||
pump = "UpLeft,UpRight,UpLeft,UpRight,Center",
|
||||
},
|
||||
PreviousScrollSpeed = {
|
||||
default = "",
|
||||
dance = "Down,Right,Up,Right,Down",
|
||||
pump = "UpRight,UpLeft,UpRight,UpLeft,Center",
|
||||
},
|
||||
NextAccel = {
|
||||
default = "",
|
||||
dance = "Left,Right,Down,Up",
|
||||
},
|
||||
NextEffect = {
|
||||
default = "",
|
||||
dance = "Left,Down,Right",
|
||||
},
|
||||
NextAppearance = {
|
||||
default = "",
|
||||
dance = "Left,Up,Right",
|
||||
},
|
||||
NextTurn = {
|
||||
default = "",
|
||||
},
|
||||
-- cancel all in player options
|
||||
CancelAllPlayerOptions = {
|
||||
default = "",
|
||||
dance = "Left,Right,Left,Right,Left,Right",
|
||||
},
|
||||
};
|
||||
|
||||
function GetCodeForGame(codeName)
|
||||
local gameName = string.lower(CurGameName())
|
||||
local inputCode = CodeDetectorCodes[codeName]
|
||||
return inputCode[gameName] or inputCode["default"]
|
||||
end
|
||||
|
||||
@@ -1322,6 +1322,24 @@ LevelP2Y=
|
||||
LevelP2OnCommand=
|
||||
LevelP2OffCommand=
|
||||
|
||||
FrameBaseP1X=
|
||||
FrameBaseP1Y=
|
||||
FrameBaseP1OnCommand=
|
||||
FrameBaseP1OffCommand=
|
||||
FrameBaseP2X=
|
||||
FrameBaseP2Y=
|
||||
FrameBaseP2OnCommand=
|
||||
FrameBaseP2OffCommand=
|
||||
|
||||
FrameOverP1X=
|
||||
FrameOverP1Y=
|
||||
FrameOverP1OnCommand=
|
||||
FrameOverP1OffCommand=
|
||||
FrameOverP2X=
|
||||
FrameOverP2Y=
|
||||
FrameOverP2OnCommand=
|
||||
FrameOverP2OffCommand=
|
||||
|
||||
[ScoreKeeperRave]
|
||||
AttackDurationSeconds=3.0
|
||||
|
||||
@@ -3822,7 +3840,7 @@ ShowCreditDisplay=false
|
||||
ShowStyleIcon=false
|
||||
InvertScrollSpeedButtons=false
|
||||
TimerSeconds=-1
|
||||
EditModifiers=""
|
||||
EditModifiers="no reverse"
|
||||
EditHelpX=SCREEN_LEFT+4
|
||||
EditHelpY=SCREEN_TOP+16
|
||||
EditHelpOnCommand=halign,0;valign,0;zoom,0.5;shadowlength,1
|
||||
@@ -3923,7 +3941,7 @@ ShowStyleIcon=false
|
||||
|
||||
LineNames="1,2,3,4,5,6,R,7,8,9,10,Attacks,11,12,13,14,15,16"
|
||||
# uses legacy speed line
|
||||
Line1="lua,SpeedMods()"
|
||||
Line1="list,Speed"
|
||||
Line2="list,Accel"
|
||||
Line3="list,Effect"
|
||||
Line4="list,Appearance"
|
||||
@@ -4457,6 +4475,7 @@ Class="ScreenAttract"
|
||||
NextScreen="ScreenInit"
|
||||
PrevScreen="ScreenInit"
|
||||
TimerSeconds=3600
|
||||
TimerStealth=true
|
||||
ShowCreditDisplay=false
|
||||
|
||||
[ScreenTitleJoin]
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
#LYRICSPATH:;
|
||||
#CDTITLE:;
|
||||
#MUSIC:_gameplay sync music.ogg;
|
||||
#OFFSET:-0.012;
|
||||
#OFFSET:-0.025;
|
||||
#SAMPLESTART:0.000;
|
||||
#SAMPLELENGTH:12.000;
|
||||
#SELECTABLE:YES;
|
||||
#BPMS:0.000=132.000;
|
||||
#BPMS:0.000=132.027;
|
||||
#STOPS:;
|
||||
#BGCHANGES:;
|
||||
#KEYSOUNDS:;
|
||||
|
||||
+1032
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,93 @@
|
||||
// Adapted from http://www.codeproject.com/KB/files/zip_utils.aspx
|
||||
|
||||
#ifndef CreateZip_H
|
||||
#define CreateZip_H
|
||||
|
||||
|
||||
// ZIP functions -- for creating zip files
|
||||
// This file is a repackaged form of the Info-Zip source code available
|
||||
// at www.info-zip.org. The original copyright notice may be found in
|
||||
// zip.cpp. The repackaging was done by Lucian Wischik to simplify and
|
||||
// extend its use in Windows/C++. Also to add encryption and unicode.
|
||||
|
||||
|
||||
class TZip;
|
||||
class RageFile;
|
||||
|
||||
typedef unsigned long ZRESULT;
|
||||
// return codes from any of the zip functions. Listed later.
|
||||
|
||||
|
||||
class CreateZip
|
||||
{
|
||||
TZip* hz;
|
||||
public:
|
||||
CreateZip();
|
||||
bool Start(RageFile *f);
|
||||
bool AddFile(RString fn);
|
||||
bool AddDir(RString fn);
|
||||
bool Finish();
|
||||
RString GetError();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// e.g.
|
||||
//
|
||||
// (1) Traditional use, creating a zipfile from existing files
|
||||
// HZIP hz = CreateZip("c:\\simple1.zip",0);
|
||||
// ZipAdd(hz,"znsimple.bmp", "c:\\simple.bmp");
|
||||
// ZipAdd(hz,"znsimple.txt", "c:\\simple.txt");
|
||||
// CloseZip(hz);
|
||||
//
|
||||
// (2) Memory use, creating an auto-allocated mem-based zip file from various sources
|
||||
// HZIP hz = CreateZip(0,100000, 0);
|
||||
// // adding a conventional file...
|
||||
// ZipAdd(hz,"src1.txt", "c:\\src1.txt");
|
||||
// // adding something from memory...
|
||||
// char buf[1000]; for (int i=0; i<1000; i++) buf[i]=(char)(i&0x7F);
|
||||
// ZipAdd(hz,"file.dat", buf,1000);
|
||||
// // adding something from a pipe...
|
||||
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,NULL,0);
|
||||
// HANDLE hthread = CreateThread(0,0,ThreadFunc,(void*)hwrite,0,0);
|
||||
// ZipAdd(hz,"unz3.dat", hread,1000); // the '1000' is optional.
|
||||
// WaitForSingleObject(hthread,INFINITE);
|
||||
// CloseHandle(hthread); CloseHandle(hread);
|
||||
// ... meanwhile DWORD WINAPI ThreadFunc(void *dat)
|
||||
// { HANDLE hwrite = (HANDLE)dat;
|
||||
// char buf[1000]={17};
|
||||
// DWORD writ; WriteFile(hwrite,buf,1000,&writ,NULL);
|
||||
// CloseHandle(hwrite);
|
||||
// return 0;
|
||||
// }
|
||||
// // and now that the zip is created, let's do something with it:
|
||||
// void *zbuf; unsigned long zlen; ZipGetMemory(hz,&zbuf,&zlen);
|
||||
// HANDLE hfz = CreateFile("test2.zip",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
|
||||
// DWORD writ; WriteFile(hfz,zbuf,zlen,&writ,NULL);
|
||||
// CloseHandle(hfz);
|
||||
// CloseZip(hz);
|
||||
//
|
||||
// (3) Handle use, for file handles and pipes
|
||||
// HANDLE hzread,hzwrite; CreatePipe(&hzread,&hzwrite,0,0);
|
||||
// HANDLE hthread = CreateThread(0,0,ZipReceiverThread,(void*)hzread,0,0);
|
||||
// HZIP hz = CreateZipHandle(hzwrite,0);
|
||||
// // ... add to it
|
||||
// CloseZip(hz);
|
||||
// CloseHandle(hzwrite);
|
||||
// WaitForSingleObject(hthread,INFINITE);
|
||||
// CloseHandle(hthread);
|
||||
// ... meanwhile DWORD WINAPI ZipReceiverThread(void *dat)
|
||||
// { HANDLE hread = (HANDLE)dat;
|
||||
// char buf[1000];
|
||||
// while (true)
|
||||
// { DWORD red; ReadFile(hread,buf,1000,&red,NULL);
|
||||
// // ... and do something with this zip data we're receiving
|
||||
// if (red==0) break;
|
||||
// }
|
||||
// CloseHandle(hread);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
|
||||
#endif
|
||||
@@ -136,6 +136,7 @@ Course.cpp Course.h \
|
||||
CourseLoaderCRS.cpp CourseLoaderCRS.h \
|
||||
CourseUtil.cpp CourseUtil.h \
|
||||
CourseWriterCRS.cpp CourseWriterCRS.h \
|
||||
CreateZip.cpp CreateZip.h \
|
||||
CryptHelpers.cpp CryptHelpers.h \
|
||||
DateTime.cpp DateTime.h \
|
||||
Difficulty.cpp Difficulty.h \
|
||||
|
||||
+40
-40
@@ -1,40 +1,40 @@
|
||||
/* NotesWriterJson - Writes a Song to a .json file. */
|
||||
|
||||
#ifndef NotesWriterJson_H
|
||||
#define NotesWriterJson_H
|
||||
|
||||
class Song;
|
||||
class Steps;
|
||||
|
||||
namespace NotesWriterJson
|
||||
{
|
||||
static bool WriteSong( const RString &sFile, const Song &out, bool bWriteSteps );
|
||||
static bool WriteSteps( const RString &sFile, const Steps &out );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* (c) 2001-2010 Chris Danford, Glenn Maynard
|
||||
* 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.
|
||||
*/
|
||||
/* NotesWriterJson - Writes a Song to a .json file. */
|
||||
|
||||
#ifndef NotesWriterJson_H
|
||||
#define NotesWriterJson_H
|
||||
|
||||
class Song;
|
||||
class Steps;
|
||||
|
||||
namespace NotesWriterJson
|
||||
{
|
||||
bool WriteSong( const RString &sFile, const Song &out, bool bWriteSteps );
|
||||
bool WriteSteps( const RString &sFile, const Steps &out );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* (c) 2001-2010 Chris Danford, Glenn Maynard
|
||||
* 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.
|
||||
*/
|
||||
|
||||
+2346
-2343
File diff suppressed because it is too large
Load Diff
+95
-91
@@ -1,91 +1,95 @@
|
||||
#include "global.h"
|
||||
#include "ScoreDisplayRave.h"
|
||||
#include "RageUtil.h"
|
||||
#include "RageLog.h"
|
||||
#include "ThemeManager.h"
|
||||
#include "ActorUtil.h"
|
||||
#include "PlayerState.h"
|
||||
|
||||
|
||||
ScoreDisplayRave::ScoreDisplayRave()
|
||||
{
|
||||
LOG->Trace( "ScoreDisplayRave::ScoreDisplayRave()" );
|
||||
|
||||
m_lastLevelSeen = ATTACK_LEVEL_1;
|
||||
|
||||
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
|
||||
{
|
||||
m_sprMeter[i].Load( THEME->GetPathG("ScoreDisplayRave",ssprintf("stream level%d",i+1)) );
|
||||
m_sprMeter[i].SetCropRight( 1.f );
|
||||
}
|
||||
|
||||
m_textLevel.LoadFromFont( THEME->GetPathF("ScoreDisplayRave","level") );
|
||||
m_textLevel.SetText( "1" );
|
||||
}
|
||||
|
||||
void ScoreDisplayRave::Init( const PlayerState* pPlayerState, const PlayerStageStats* pPlayerStageStats )
|
||||
{
|
||||
ScoreDisplay::Init( pPlayerState, pPlayerStageStats );
|
||||
|
||||
PlayerNumber pn = pPlayerState->m_PlayerNumber;
|
||||
|
||||
m_sprFrameBase.Load( THEME->GetPathG("ScoreDisplayRave",ssprintf("frame base p%d",pn+1)) );
|
||||
this->AddChild( m_sprFrameBase );
|
||||
|
||||
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
|
||||
{
|
||||
m_sprMeter[i].SetName( ssprintf("MeterP%d",pn+1) );
|
||||
LOAD_ALL_COMMANDS_AND_SET_XY( m_sprMeter[i] );
|
||||
this->AddChild( &m_sprMeter[i] );
|
||||
}
|
||||
|
||||
m_textLevel.SetName( ssprintf("LevelP%d",pn+1) );
|
||||
LOAD_ALL_COMMANDS_AND_SET_XY( m_textLevel );
|
||||
this->AddChild( &m_textLevel );
|
||||
|
||||
m_sprFrameOverlay.Load( THEME->GetPathG("ScoreDisplayRave",ssprintf("frame overlay p%d",pn+1)) );
|
||||
this->AddChild( m_sprFrameOverlay );
|
||||
}
|
||||
|
||||
void ScoreDisplayRave::Update( float fDelta )
|
||||
{
|
||||
ScoreDisplay::Update( fDelta );
|
||||
|
||||
float fLevel = m_pPlayerState->m_fSuperMeter;
|
||||
AttackLevel level = (AttackLevel)(int)fLevel;
|
||||
|
||||
if( level != m_lastLevelSeen )
|
||||
{
|
||||
m_sprMeter[m_lastLevelSeen].SetCropRight( 1.f );
|
||||
m_lastLevelSeen = level;
|
||||
m_textLevel.SetText( ssprintf("%d",level+1) );
|
||||
}
|
||||
|
||||
float fPercent = fLevel - level;
|
||||
m_sprMeter[level].SetCropRight( 1-fPercent );
|
||||
}
|
||||
|
||||
/*
|
||||
* (c) 2003 Chris Danford
|
||||
* 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.
|
||||
*/
|
||||
#include "global.h"
|
||||
#include "ScoreDisplayRave.h"
|
||||
#include "RageUtil.h"
|
||||
#include "RageLog.h"
|
||||
#include "ThemeManager.h"
|
||||
#include "ActorUtil.h"
|
||||
#include "PlayerState.h"
|
||||
|
||||
|
||||
ScoreDisplayRave::ScoreDisplayRave()
|
||||
{
|
||||
LOG->Trace( "ScoreDisplayRave::ScoreDisplayRave()" );
|
||||
|
||||
m_lastLevelSeen = ATTACK_LEVEL_1;
|
||||
|
||||
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
|
||||
{
|
||||
m_sprMeter[i].Load( THEME->GetPathG("ScoreDisplayRave",ssprintf("stream level%d",i+1)) );
|
||||
m_sprMeter[i].SetCropRight( 1.f );
|
||||
}
|
||||
|
||||
m_textLevel.LoadFromFont( THEME->GetPathF("ScoreDisplayRave","level") );
|
||||
m_textLevel.SetText( "1" );
|
||||
}
|
||||
|
||||
void ScoreDisplayRave::Init( const PlayerState* pPlayerState, const PlayerStageStats* pPlayerStageStats )
|
||||
{
|
||||
ScoreDisplay::Init( pPlayerState, pPlayerStageStats );
|
||||
|
||||
PlayerNumber pn = pPlayerState->m_PlayerNumber;
|
||||
|
||||
m_sprFrameBase.Load( THEME->GetPathG("ScoreDisplayRave",ssprintf("frame base p%d",pn+1)) );
|
||||
m_sprFrameBase->SetName( ssprintf("FrameBaseP%d",pn+1) );
|
||||
LOAD_ALL_COMMANDS_AND_SET_XY( m_sprFrameBase );
|
||||
this->AddChild( m_sprFrameBase );
|
||||
|
||||
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
|
||||
{
|
||||
m_sprMeter[i].SetName( ssprintf("MeterP%d",pn+1) );
|
||||
LOAD_ALL_COMMANDS_AND_SET_XY( m_sprMeter[i] );
|
||||
this->AddChild( &m_sprMeter[i] );
|
||||
}
|
||||
|
||||
m_textLevel.SetName( ssprintf("LevelP%d",pn+1) );
|
||||
LOAD_ALL_COMMANDS_AND_SET_XY( m_textLevel );
|
||||
this->AddChild( &m_textLevel );
|
||||
|
||||
m_sprFrameOverlay.Load( THEME->GetPathG("ScoreDisplayRave",ssprintf("frame overlay p%d",pn+1)) );
|
||||
m_sprFrameOverlay->SetName( ssprintf("FrameOverP%d",pn+1) );
|
||||
LOAD_ALL_COMMANDS_AND_SET_XY( m_sprFrameOverlay );
|
||||
this->AddChild( m_sprFrameOverlay );
|
||||
}
|
||||
|
||||
void ScoreDisplayRave::Update( float fDelta )
|
||||
{
|
||||
ScoreDisplay::Update( fDelta );
|
||||
|
||||
float fLevel = m_pPlayerState->m_fSuperMeter;
|
||||
AttackLevel level = (AttackLevel)(int)fLevel;
|
||||
|
||||
if( level != m_lastLevelSeen )
|
||||
{
|
||||
m_sprMeter[m_lastLevelSeen].SetCropRight( 1.f );
|
||||
m_lastLevelSeen = level;
|
||||
m_textLevel.SetText( ssprintf("%d",level+1) );
|
||||
}
|
||||
|
||||
float fPercent = fLevel - level;
|
||||
m_sprMeter[level].SetCropRight( 1-fPercent );
|
||||
}
|
||||
|
||||
/*
|
||||
* (c) 2003 Chris Danford
|
||||
* 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.
|
||||
*/
|
||||
|
||||
+2955
-2944
File diff suppressed because it is too large
Load Diff
+356
-353
@@ -1,353 +1,356 @@
|
||||
#include "global.h"
|
||||
#include "ScreenHowToPlay.h"
|
||||
#include "ThemeManager.h"
|
||||
#include "GameState.h"
|
||||
#include "Steps.h"
|
||||
#include "GameManager.h"
|
||||
#include "NotesLoaderSM.h"
|
||||
#include "NotesLoaderSSC.h"
|
||||
#include "GameSoundManager.h"
|
||||
#include "Model.h"
|
||||
#include "ThemeMetric.h"
|
||||
#include "PlayerState.h"
|
||||
#include "Style.h"
|
||||
#include "PrefsManager.h"
|
||||
#include "CharacterManager.h"
|
||||
#include "StatsManager.h"
|
||||
#include "RageDisplay.h"
|
||||
#include "SongUtil.h"
|
||||
#include "Character.h"
|
||||
#include "LifeMeterBar.h"
|
||||
|
||||
static const ThemeMetric<int> NUM_W2S ("ScreenHowToPlay","NumW2s");
|
||||
static const ThemeMetric<int> NUM_MISSES ("ScreenHowToPlay","NumMisses");
|
||||
static const ThemeMetric<bool> USE_CHARACTER ("ScreenHowToPlay","UseCharacter");
|
||||
static const ThemeMetric<bool> USE_PAD ("ScreenHowToPlay","UsePad");
|
||||
static const ThemeMetric<bool> USE_PLAYER ("ScreenHowToPlay","UsePlayer");
|
||||
static const ThemeMetric<RString> CHARACTER_NAME("ScreenHowToPlay","CharacterName");
|
||||
|
||||
enum Animation
|
||||
{
|
||||
ANIM_DANCE_PAD,
|
||||
ANIM_DANCE_PADS,
|
||||
ANIM_UP,
|
||||
ANIM_DOWN,
|
||||
ANIM_LEFT,
|
||||
ANIM_RIGHT,
|
||||
ANIM_JUMPLR,
|
||||
NUM_ANIMATIONS
|
||||
};
|
||||
|
||||
static const RString anims[NUM_ANIMATIONS] =
|
||||
{
|
||||
"DancePad.txt",
|
||||
"DancePads.txt",
|
||||
"BeginnerHelper_step-up.bones.txt",
|
||||
"BeginnerHelper_step-down.bones.txt",
|
||||
"BeginnerHelper_step-left.bones.txt",
|
||||
"BeginnerHelper_step-right.bones.txt",
|
||||
"BeginnerHelper_step-jumplr.bones.txt"
|
||||
};
|
||||
|
||||
static RString GetAnimPath( Animation a )
|
||||
{
|
||||
return RString("Characters/") + anims[a];
|
||||
}
|
||||
|
||||
static bool HaveAllCharAnimations()
|
||||
{
|
||||
for( int i = ANIM_UP; i < NUM_ANIMATIONS; ++i )
|
||||
if( !DoesFileExist( GetAnimPath( (Animation) i ) ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
REGISTER_SCREEN_CLASS( ScreenHowToPlay );
|
||||
ScreenHowToPlay::ScreenHowToPlay()
|
||||
{
|
||||
m_iW2s = 0;
|
||||
m_iNumW2s = NUM_W2S;
|
||||
|
||||
// initialize these because they might not be used.
|
||||
m_pLifeMeterBar = NULL;
|
||||
m_pmCharacter = NULL;
|
||||
m_pmDancePad = NULL;
|
||||
}
|
||||
|
||||
void ScreenHowToPlay::Init()
|
||||
{
|
||||
ScreenAttract::Init();
|
||||
|
||||
if( (bool)USE_PAD && DoesFileExist( GetAnimPath(ANIM_DANCE_PAD) ) )
|
||||
{
|
||||
m_pmDancePad = new Model;
|
||||
m_pmDancePad->SetName( "Pad" );
|
||||
m_pmDancePad->LoadMilkshapeAscii( GetAnimPath(ANIM_DANCE_PAD) );
|
||||
// xxx: hardcoded rotation. can be undone, but still. -freem
|
||||
m_pmDancePad->SetRotationX( 35 );
|
||||
ActorUtil::LoadAllCommandsAndSetXY( m_pmDancePad, m_sName );
|
||||
}
|
||||
|
||||
// Display a character
|
||||
vector<Character*> vpCharacters;
|
||||
CHARMAN->GetCharacters( vpCharacters );
|
||||
if( (bool)USE_CHARACTER && vpCharacters.size() && HaveAllCharAnimations() )
|
||||
{
|
||||
Character* displayChar;
|
||||
if( !CHARACTER_NAME.GetValue().empty() && CHARMAN->GetCharacterFromID(CHARACTER_NAME) )
|
||||
displayChar = CHARMAN->GetCharacterFromID(CHARACTER_NAME);
|
||||
else
|
||||
displayChar = CHARMAN->GetRandomCharacter();
|
||||
|
||||
RString sModelPath = displayChar->GetModelPath();
|
||||
if( sModelPath != "" )
|
||||
{
|
||||
m_pmCharacter = new Model;
|
||||
m_pmCharacter->SetName( "Character" );
|
||||
m_pmCharacter->LoadMilkshapeAscii( displayChar->GetModelPath() );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-LEFT", GetAnimPath( ANIM_LEFT ) );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-DOWN", GetAnimPath( ANIM_DOWN ) );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-UP", GetAnimPath( ANIM_UP ) );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-RIGHT", GetAnimPath( ANIM_RIGHT ) );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-JUMPLR", GetAnimPath( ANIM_JUMPLR ) );
|
||||
RString sRestFile = displayChar->GetRestAnimationPath();
|
||||
ASSERT( !sRestFile.empty() );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "rest",displayChar->GetRestAnimationPath() );
|
||||
m_pmCharacter->SetDefaultAnimation( "rest" );
|
||||
m_pmCharacter->PlayAnimation( "rest" ); // Stay bouncing after a step has finished animating.
|
||||
|
||||
// xxx: hardcoded rotation. can be undone, but still. -freem
|
||||
m_pmCharacter->SetRotationX( 40 );
|
||||
m_pmCharacter->SetCullMode( CULL_NONE ); // many of the models floating around have the vertex order flipped
|
||||
ActorUtil::LoadAllCommandsAndSetXY( m_pmCharacter, m_sName );
|
||||
}
|
||||
}
|
||||
|
||||
GAMESTATE->SetCurrentStyle( GAMEMAN->GetHowToPlayStyleForGame(GAMESTATE->m_pCurGame) );
|
||||
|
||||
if( USE_PLAYER )
|
||||
{
|
||||
m_pLifeMeterBar = new LifeMeterBar;
|
||||
m_pLifeMeterBar->SetName("LifeMeterBar");
|
||||
m_pLifeMeterBar->Load( GAMESTATE->m_pPlayerState[PLAYER_1], &STATSMAN->m_CurStageStats.m_player[PLAYER_1] );
|
||||
ActorUtil::LoadAllCommandsAndSetXY( m_pLifeMeterBar, m_sName );
|
||||
m_pLifeMeterBar->FillForHowToPlay( NUM_W2S, NUM_MISSES );
|
||||
|
||||
// Allow themers to use either a .ssc or .sm file for this. -aj
|
||||
RString sStepsPath = THEME->GetPathO(m_sName, "steps");
|
||||
SSCLoader loaderSSC;
|
||||
SMLoader loaderSM;
|
||||
if( sStepsPath.Right(4) == ".ssc" )
|
||||
loaderSSC.LoadFromSimfile( sStepsPath, m_Song, false );
|
||||
else
|
||||
loaderSM.LoadFromSimfile( sStepsPath, m_Song, false );
|
||||
m_Song.AddAutoGenNotes();
|
||||
|
||||
const Style* pStyle = GAMESTATE->GetCurrentStyle();
|
||||
|
||||
Steps *pSteps = SongUtil::GetClosestNotes( &m_Song, pStyle->m_StepsType, Difficulty_Beginner );
|
||||
ASSERT_M( pSteps != NULL, ssprintf("No playable steps of StepsType '%s' for ScreenHowToPlay", StringConversion::ToString(pStyle->m_StepsType).c_str()) );
|
||||
|
||||
pSteps->m_Timing.TidyUpData();
|
||||
NoteData tempNoteData;
|
||||
pSteps->GetNoteData( tempNoteData );
|
||||
pStyle->GetTransformedNoteDataForStyle( PLAYER_1, tempNoteData, m_NoteData );
|
||||
|
||||
GAMESTATE->m_pCurSong.Set( &m_Song );
|
||||
GAMESTATE->m_pCurSteps[PLAYER_1].Set(pSteps);
|
||||
GAMESTATE->m_bGameplayLeadIn.Set( false );
|
||||
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerController = PC_AUTOPLAY;
|
||||
|
||||
m_Player->Init(
|
||||
"Player",
|
||||
GAMESTATE->m_pPlayerState[PLAYER_1],
|
||||
NULL,
|
||||
m_pLifeMeterBar,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL );
|
||||
m_Player.Load( m_NoteData );
|
||||
m_Player->SetName( "Player" );
|
||||
this->AddChild( m_Player );
|
||||
ActorUtil::LoadAllCommandsAndSetXY( m_Player, m_sName );
|
||||
|
||||
// Don't show judgment
|
||||
PO_GROUP_ASSIGN( GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions, ModsLevel_Stage, m_fBlind, 1.0f );
|
||||
GAMESTATE->SetMasterPlayerNumber(PLAYER_1);
|
||||
GAMESTATE->m_bDemonstrationOrJukebox = true;
|
||||
}
|
||||
|
||||
// deferred until after the player, so the notes go under it
|
||||
if( m_pLifeMeterBar )
|
||||
this->AddChild( m_pLifeMeterBar );
|
||||
if( m_pmDancePad )
|
||||
this->AddChild( m_pmDancePad );
|
||||
if( m_pmCharacter )
|
||||
this->AddChild( m_pmCharacter );
|
||||
|
||||
m_fFakeSecondsIntoSong = 0;
|
||||
|
||||
this->MoveToTail( &m_In );
|
||||
this->MoveToTail( &m_Out );
|
||||
}
|
||||
|
||||
ScreenHowToPlay::~ScreenHowToPlay()
|
||||
{
|
||||
delete m_pLifeMeterBar;
|
||||
delete m_pmCharacter;
|
||||
delete m_pmDancePad;
|
||||
}
|
||||
|
||||
void ScreenHowToPlay::Step()
|
||||
{
|
||||
// xxx: assumes dance. -freem
|
||||
#define ST_LEFT 0x01
|
||||
#define ST_DOWN 0x02
|
||||
#define ST_UP 0x04
|
||||
#define ST_RIGHT 0x08
|
||||
#define ST_JUMPLR (ST_LEFT | ST_RIGHT)
|
||||
#define ST_JUMPUD (ST_UP | ST_DOWN)
|
||||
|
||||
int iStep = 0;
|
||||
const int iNoteRow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat + 0.6f );
|
||||
// if we want to miss from here on out, don't process steps.
|
||||
if( m_iW2s < m_iNumW2s && m_NoteData.IsThereATapAtRow( iNoteRow ) )
|
||||
{
|
||||
const int iNumTracks = m_NoteData.GetNumTracks();
|
||||
for( int k=0; k<iNumTracks; k++ )
|
||||
if( m_NoteData.GetTapNote(k, iNoteRow).type == TapNote::tap )
|
||||
iStep |= 1 << k;
|
||||
|
||||
switch( iStep )
|
||||
{
|
||||
case ST_LEFT: m_pmCharacter->PlayAnimation( "Step-LEFT", 1.8f ); break;
|
||||
case ST_RIGHT: m_pmCharacter->PlayAnimation( "Step-RIGHT", 1.8f ); break;
|
||||
case ST_UP: m_pmCharacter->PlayAnimation( "Step-UP", 1.8f ); break;
|
||||
case ST_DOWN: m_pmCharacter->PlayAnimation( "Step-DOWN", 1.8f ); break;
|
||||
case ST_JUMPLR: m_pmCharacter->PlayAnimation( "Step-JUMPLR", 1.8f ); break;
|
||||
case ST_JUMPUD:
|
||||
// Until I can get an UP+DOWN jump animation, this will have to do.
|
||||
m_pmCharacter->PlayAnimation( "Step-JUMPLR", 1.8f );
|
||||
|
||||
m_pmCharacter->StopTweening();
|
||||
m_pmCharacter->BeginTweening( GAMESTATE->m_Position.m_fCurBPS /8, TWEEN_LINEAR );
|
||||
m_pmCharacter->SetRotationY( 90 );
|
||||
m_pmCharacter->BeginTweening( (1/(GAMESTATE->m_Position.m_fCurBPS * 2) ) ); //sleep between jump-frames
|
||||
m_pmCharacter->BeginTweening( GAMESTATE->m_Position.m_fCurBPS /6, TWEEN_LINEAR );
|
||||
m_pmCharacter->SetRotationY( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenHowToPlay::Update( float fDelta )
|
||||
{
|
||||
if( GAMESTATE->m_pCurSong != NULL )
|
||||
{
|
||||
GAMESTATE->UpdateSongPosition( m_fFakeSecondsIntoSong, GAMESTATE->m_pCurSong->m_SongTiming );
|
||||
m_fFakeSecondsIntoSong += fDelta;
|
||||
|
||||
static int iLastNoteRowCounted = 0;
|
||||
int iCurNoteRow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat );
|
||||
|
||||
if( iCurNoteRow != iLastNoteRowCounted &&m_NoteData.IsThereATapAtRow(iCurNoteRow) )
|
||||
{
|
||||
if( m_pLifeMeterBar && !m_Player )
|
||||
{
|
||||
if ( m_iW2s < m_iNumW2s )
|
||||
m_pLifeMeterBar->ChangeLife( TNS_W2 );
|
||||
else
|
||||
m_pLifeMeterBar->ChangeLife( TNS_Miss );
|
||||
}
|
||||
m_iW2s++;
|
||||
iLastNoteRowCounted = iCurNoteRow;
|
||||
}
|
||||
|
||||
// Once we hit the number of perfects we want, we want to fail. Switch
|
||||
// the controller to HUMAN. Since we aren't taking input, the steps will
|
||||
// always be misses.
|
||||
if( m_iW2s > m_iNumW2s )
|
||||
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerController = PC_HUMAN;
|
||||
|
||||
// Per the above code, we don't always want the character stepping.
|
||||
// If they try to make all of the steps in the miss part, they look
|
||||
// silly. Have then stand still instead. - freem
|
||||
if ( m_pmCharacter )
|
||||
{
|
||||
if( m_iW2s <= m_iNumW2s )
|
||||
Step();
|
||||
}
|
||||
}
|
||||
|
||||
ScreenAttract::Update( fDelta );
|
||||
}
|
||||
|
||||
void ScreenHowToPlay::HandleScreenMessage( const ScreenMessage SM )
|
||||
{
|
||||
if( SM == SM_GainFocus )
|
||||
{
|
||||
// We do this ourself.
|
||||
SOUND->HandleSongTimer( false );
|
||||
}
|
||||
else if( SM == SM_LoseFocus )
|
||||
{
|
||||
SOUND->HandleSongTimer( true );
|
||||
}
|
||||
else if( SM == SM_GoToNextScreen )
|
||||
{
|
||||
GAMESTATE->Reset();
|
||||
}
|
||||
ScreenAttract::HandleScreenMessage( SM );
|
||||
}
|
||||
|
||||
// lua start
|
||||
#include "LuaBinding.h"
|
||||
|
||||
/** @brief Allow Lua to have access to the ScreenHowToPlay. */
|
||||
class LunaScreenHowToPlay: public Luna<ScreenHowToPlay>
|
||||
{
|
||||
public:
|
||||
static int GetLifeMeter( T* p, lua_State *L )
|
||||
{
|
||||
//PlayerNumber pn = Enum::Check<PlayerNumber>( L, 1 );
|
||||
|
||||
p->m_pLifeMeterBar->PushSelf( L );
|
||||
return 1;
|
||||
}
|
||||
|
||||
LunaScreenHowToPlay()
|
||||
{
|
||||
ADD_METHOD( GetLifeMeter );
|
||||
}
|
||||
};
|
||||
|
||||
LUA_REGISTER_DERIVED_CLASS( ScreenHowToPlay, ScreenAttract )
|
||||
// lua end
|
||||
|
||||
/*
|
||||
* (c) 2001-2004 Chris Danford, Thad Ward
|
||||
* 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.
|
||||
*/
|
||||
#include "global.h"
|
||||
#include "ScreenHowToPlay.h"
|
||||
#include "ThemeManager.h"
|
||||
#include "GameState.h"
|
||||
#include "Steps.h"
|
||||
#include "GameManager.h"
|
||||
#include "NotesLoaderSM.h"
|
||||
#include "NotesLoaderSSC.h"
|
||||
#include "GameSoundManager.h"
|
||||
#include "Model.h"
|
||||
#include "ThemeMetric.h"
|
||||
#include "PlayerState.h"
|
||||
#include "Style.h"
|
||||
#include "PrefsManager.h"
|
||||
#include "CharacterManager.h"
|
||||
#include "StatsManager.h"
|
||||
#include "RageDisplay.h"
|
||||
#include "SongUtil.h"
|
||||
#include "Character.h"
|
||||
#include "LifeMeterBar.h"
|
||||
|
||||
static const ThemeMetric<int> NUM_W2S ("ScreenHowToPlay","NumW2s");
|
||||
static const ThemeMetric<int> NUM_MISSES ("ScreenHowToPlay","NumMisses");
|
||||
static const ThemeMetric<bool> USE_CHARACTER ("ScreenHowToPlay","UseCharacter");
|
||||
static const ThemeMetric<bool> USE_PAD ("ScreenHowToPlay","UsePad");
|
||||
static const ThemeMetric<bool> USE_PLAYER ("ScreenHowToPlay","UsePlayer");
|
||||
static const ThemeMetric<RString> CHARACTER_NAME("ScreenHowToPlay","CharacterName");
|
||||
|
||||
enum Animation
|
||||
{
|
||||
ANIM_DANCE_PAD,
|
||||
ANIM_DANCE_PADS,
|
||||
ANIM_UP,
|
||||
ANIM_DOWN,
|
||||
ANIM_LEFT,
|
||||
ANIM_RIGHT,
|
||||
ANIM_JUMPLR,
|
||||
NUM_ANIMATIONS
|
||||
};
|
||||
|
||||
static const RString anims[NUM_ANIMATIONS] =
|
||||
{
|
||||
"DancePad.txt",
|
||||
"DancePads.txt",
|
||||
"BeginnerHelper_step-up.bones.txt",
|
||||
"BeginnerHelper_step-down.bones.txt",
|
||||
"BeginnerHelper_step-left.bones.txt",
|
||||
"BeginnerHelper_step-right.bones.txt",
|
||||
"BeginnerHelper_step-jumplr.bones.txt"
|
||||
};
|
||||
|
||||
static RString GetAnimPath( Animation a )
|
||||
{
|
||||
return RString("Characters/") + anims[a];
|
||||
}
|
||||
|
||||
static bool HaveAllCharAnimations()
|
||||
{
|
||||
for( int i = ANIM_UP; i < NUM_ANIMATIONS; ++i )
|
||||
if( !DoesFileExist( GetAnimPath( (Animation) i ) ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
REGISTER_SCREEN_CLASS( ScreenHowToPlay );
|
||||
ScreenHowToPlay::ScreenHowToPlay()
|
||||
{
|
||||
m_iW2s = 0;
|
||||
m_iNumW2s = NUM_W2S;
|
||||
|
||||
// initialize these because they might not be used.
|
||||
m_pLifeMeterBar = NULL;
|
||||
m_pmCharacter = NULL;
|
||||
m_pmDancePad = NULL;
|
||||
}
|
||||
|
||||
void ScreenHowToPlay::Init()
|
||||
{
|
||||
ScreenAttract::Init();
|
||||
|
||||
if( (bool)USE_PAD && DoesFileExist( GetAnimPath(ANIM_DANCE_PAD) ) )
|
||||
{
|
||||
m_pmDancePad = new Model;
|
||||
m_pmDancePad->SetName( "Pad" );
|
||||
m_pmDancePad->LoadMilkshapeAscii( GetAnimPath(ANIM_DANCE_PAD) );
|
||||
// xxx: hardcoded rotation. can be undone, but still. -freem
|
||||
m_pmDancePad->SetRotationX( 35 );
|
||||
ActorUtil::LoadAllCommandsAndSetXY( m_pmDancePad, m_sName );
|
||||
}
|
||||
|
||||
// Display a character
|
||||
vector<Character*> vpCharacters;
|
||||
CHARMAN->GetCharacters( vpCharacters );
|
||||
if( (bool)USE_CHARACTER && vpCharacters.size() && HaveAllCharAnimations() )
|
||||
{
|
||||
Character* displayChar;
|
||||
if( !CHARACTER_NAME.GetValue().empty() && CHARMAN->GetCharacterFromID(CHARACTER_NAME) )
|
||||
displayChar = CHARMAN->GetCharacterFromID(CHARACTER_NAME);
|
||||
else
|
||||
displayChar = CHARMAN->GetRandomCharacter();
|
||||
|
||||
RString sModelPath = displayChar->GetModelPath();
|
||||
if( sModelPath != "" )
|
||||
{
|
||||
m_pmCharacter = new Model;
|
||||
m_pmCharacter->SetName( "Character" );
|
||||
m_pmCharacter->LoadMilkshapeAscii( displayChar->GetModelPath() );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-LEFT", GetAnimPath( ANIM_LEFT ) );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-DOWN", GetAnimPath( ANIM_DOWN ) );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-UP", GetAnimPath( ANIM_UP ) );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-RIGHT", GetAnimPath( ANIM_RIGHT ) );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "Step-JUMPLR", GetAnimPath( ANIM_JUMPLR ) );
|
||||
RString sRestFile = displayChar->GetRestAnimationPath();
|
||||
ASSERT( !sRestFile.empty() );
|
||||
m_pmCharacter->LoadMilkshapeAsciiBones( "rest",displayChar->GetRestAnimationPath() );
|
||||
m_pmCharacter->SetDefaultAnimation( "rest" );
|
||||
m_pmCharacter->PlayAnimation( "rest" ); // Stay bouncing after a step has finished animating.
|
||||
|
||||
// xxx: hardcoded rotation. can be undone, but still. -freem
|
||||
m_pmCharacter->SetRotationX( 40 );
|
||||
m_pmCharacter->SetCullMode( CULL_NONE ); // many of the models floating around have the vertex order flipped
|
||||
m_pmCharacter->RunCommands( displayChar->m_cmdInit ); // run InitCommand from file
|
||||
ActorUtil::LoadAllCommandsAndSetXY( m_pmCharacter, m_sName );
|
||||
}
|
||||
}
|
||||
|
||||
GAMESTATE->SetCurrentStyle( GAMEMAN->GetHowToPlayStyleForGame(GAMESTATE->m_pCurGame) );
|
||||
|
||||
if( USE_PLAYER )
|
||||
{
|
||||
GAMESTATE->SetMasterPlayerNumber(PLAYER_1);
|
||||
|
||||
m_pLifeMeterBar = new LifeMeterBar;
|
||||
m_pLifeMeterBar->Load( GAMESTATE->m_pPlayerState[PLAYER_1], &STATSMAN->m_CurStageStats.m_player[PLAYER_1] );
|
||||
m_pLifeMeterBar->SetName("LifeMeterBar");
|
||||
ActorUtil::LoadAllCommandsAndSetXY( m_pLifeMeterBar, m_sName );
|
||||
m_pLifeMeterBar->FillForHowToPlay( NUM_W2S, NUM_MISSES );
|
||||
|
||||
// Allow themers to use either a .ssc or .sm file for this. -aj
|
||||
RString sStepsPath = THEME->GetPathO(m_sName, "steps");
|
||||
SSCLoader loaderSSC;
|
||||
SMLoader loaderSM;
|
||||
if( sStepsPath.Right(4) == ".ssc" )
|
||||
loaderSSC.LoadFromSimfile( sStepsPath, m_Song, false );
|
||||
else
|
||||
loaderSM.LoadFromSimfile( sStepsPath, m_Song, false );
|
||||
m_Song.AddAutoGenNotes();
|
||||
|
||||
const Style* pStyle = GAMESTATE->GetCurrentStyle();
|
||||
|
||||
Steps *pSteps = SongUtil::GetClosestNotes( &m_Song, pStyle->m_StepsType, Difficulty_Beginner );
|
||||
ASSERT_M( pSteps != NULL, ssprintf("No playable steps of StepsType '%s' for ScreenHowToPlay", StringConversion::ToString(pStyle->m_StepsType).c_str()) );
|
||||
|
||||
pSteps->m_Timing.TidyUpData();
|
||||
NoteData tempNoteData;
|
||||
pSteps->GetNoteData( tempNoteData );
|
||||
pStyle->GetTransformedNoteDataForStyle( PLAYER_1, tempNoteData, m_NoteData );
|
||||
|
||||
GAMESTATE->m_pCurSong.Set( &m_Song );
|
||||
GAMESTATE->m_pCurSteps[PLAYER_1].Set(pSteps);
|
||||
GAMESTATE->m_bGameplayLeadIn.Set( false );
|
||||
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerController = PC_AUTOPLAY;
|
||||
|
||||
m_Player->Init(
|
||||
"Player",
|
||||
GAMESTATE->m_pPlayerState[PLAYER_1],
|
||||
NULL,
|
||||
m_pLifeMeterBar,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL );
|
||||
m_Player.Load( m_NoteData );
|
||||
m_Player->SetName( "Player" );
|
||||
this->AddChild( m_Player );
|
||||
ActorUtil::LoadAllCommandsAndSetXY( m_Player, m_sName );
|
||||
|
||||
// Don't show judgment
|
||||
PO_GROUP_ASSIGN( GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions, ModsLevel_Stage, m_fBlind, 1.0f );
|
||||
GAMESTATE->m_bDemonstrationOrJukebox = true;
|
||||
}
|
||||
|
||||
// deferred until after the player, so the notes go under it
|
||||
if( m_pLifeMeterBar )
|
||||
this->AddChild( m_pLifeMeterBar );
|
||||
if( m_pmDancePad )
|
||||
this->AddChild( m_pmDancePad );
|
||||
if( m_pmCharacter )
|
||||
this->AddChild( m_pmCharacter );
|
||||
|
||||
m_fFakeSecondsIntoSong = 0;
|
||||
|
||||
this->MoveToTail( &m_In );
|
||||
this->MoveToTail( &m_Out );
|
||||
}
|
||||
|
||||
ScreenHowToPlay::~ScreenHowToPlay()
|
||||
{
|
||||
delete m_pLifeMeterBar;
|
||||
delete m_pmCharacter;
|
||||
delete m_pmDancePad;
|
||||
}
|
||||
|
||||
void ScreenHowToPlay::Step()
|
||||
{
|
||||
// xxx: assumes dance. -freem
|
||||
#define ST_LEFT 0x01
|
||||
#define ST_DOWN 0x02
|
||||
#define ST_UP 0x04
|
||||
#define ST_RIGHT 0x08
|
||||
#define ST_JUMPLR (ST_LEFT | ST_RIGHT)
|
||||
#define ST_JUMPUD (ST_UP | ST_DOWN)
|
||||
|
||||
int iStep = 0;
|
||||
const int iNoteRow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat + 0.6f );
|
||||
// if we want to miss from here on out, don't process steps.
|
||||
if( m_iW2s < m_iNumW2s && m_NoteData.IsThereATapAtRow( iNoteRow ) )
|
||||
{
|
||||
const int iNumTracks = m_NoteData.GetNumTracks();
|
||||
for( int k=0; k<iNumTracks; k++ )
|
||||
if( m_NoteData.GetTapNote(k, iNoteRow).type == TapNote::tap )
|
||||
iStep |= 1 << k;
|
||||
|
||||
switch( iStep )
|
||||
{
|
||||
case ST_LEFT: m_pmCharacter->PlayAnimation( "Step-LEFT", 1.8f ); break;
|
||||
case ST_RIGHT: m_pmCharacter->PlayAnimation( "Step-RIGHT", 1.8f ); break;
|
||||
case ST_UP: m_pmCharacter->PlayAnimation( "Step-UP", 1.8f ); break;
|
||||
case ST_DOWN: m_pmCharacter->PlayAnimation( "Step-DOWN", 1.8f ); break;
|
||||
case ST_JUMPLR: m_pmCharacter->PlayAnimation( "Step-JUMPLR", 1.8f ); break;
|
||||
case ST_JUMPUD:
|
||||
// Until I can get an UP+DOWN jump animation, this will have to do.
|
||||
m_pmCharacter->PlayAnimation( "Step-JUMPLR", 1.8f );
|
||||
|
||||
m_pmCharacter->StopTweening();
|
||||
m_pmCharacter->BeginTweening( GAMESTATE->m_Position.m_fCurBPS /8, TWEEN_LINEAR );
|
||||
m_pmCharacter->SetRotationY( 90 );
|
||||
m_pmCharacter->BeginTweening( (1/(GAMESTATE->m_Position.m_fCurBPS * 2) ) ); //sleep between jump-frames
|
||||
m_pmCharacter->BeginTweening( GAMESTATE->m_Position.m_fCurBPS /6, TWEEN_LINEAR );
|
||||
m_pmCharacter->SetRotationY( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenHowToPlay::Update( float fDelta )
|
||||
{
|
||||
if( GAMESTATE->m_pCurSong != NULL )
|
||||
{
|
||||
RageTimer tm;
|
||||
GAMESTATE->UpdateSongPosition( m_fFakeSecondsIntoSong, GAMESTATE->m_pCurSong->m_SongTiming, tm, true );
|
||||
m_fFakeSecondsIntoSong += fDelta;
|
||||
|
||||
static int iLastNoteRowCounted = 0;
|
||||
int iCurNoteRow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat );
|
||||
|
||||
if( iCurNoteRow != iLastNoteRowCounted &&m_NoteData.IsThereATapAtRow(iCurNoteRow) )
|
||||
{
|
||||
if( m_pLifeMeterBar && !m_Player )
|
||||
{
|
||||
if ( m_iW2s < m_iNumW2s )
|
||||
m_pLifeMeterBar->ChangeLife( TNS_W2 );
|
||||
else
|
||||
m_pLifeMeterBar->ChangeLife( TNS_Miss );
|
||||
}
|
||||
m_iW2s++;
|
||||
iLastNoteRowCounted = iCurNoteRow;
|
||||
}
|
||||
|
||||
// Once we hit the number of perfects we want, we want to fail. Switch
|
||||
// the controller to HUMAN. Since we aren't taking input, the steps will
|
||||
// always be misses.
|
||||
if( m_iW2s > m_iNumW2s )
|
||||
GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerController = PC_HUMAN;
|
||||
|
||||
// Per the above code, we don't always want the character stepping.
|
||||
// If they try to make all of the steps in the miss part, they look
|
||||
// silly. Have then stand still instead. - freem
|
||||
if ( m_pmCharacter )
|
||||
{
|
||||
if( m_iW2s <= m_iNumW2s )
|
||||
Step();
|
||||
}
|
||||
}
|
||||
|
||||
ScreenAttract::Update( fDelta );
|
||||
}
|
||||
|
||||
void ScreenHowToPlay::HandleScreenMessage( const ScreenMessage SM )
|
||||
{
|
||||
if( SM == SM_GainFocus )
|
||||
{
|
||||
// We do this ourself.
|
||||
SOUND->HandleSongTimer( false );
|
||||
}
|
||||
else if( SM == SM_LoseFocus )
|
||||
{
|
||||
SOUND->HandleSongTimer( true );
|
||||
}
|
||||
else if( SM == SM_GoToNextScreen )
|
||||
{
|
||||
GAMESTATE->Reset();
|
||||
}
|
||||
ScreenAttract::HandleScreenMessage( SM );
|
||||
}
|
||||
|
||||
// lua start
|
||||
#include "LuaBinding.h"
|
||||
|
||||
/** @brief Allow Lua to have access to the ScreenHowToPlay. */
|
||||
class LunaScreenHowToPlay: public Luna<ScreenHowToPlay>
|
||||
{
|
||||
public:
|
||||
static int GetLifeMeter( T* p, lua_State *L )
|
||||
{
|
||||
//PlayerNumber pn = Enum::Check<PlayerNumber>( L, 1 );
|
||||
|
||||
p->m_pLifeMeterBar->PushSelf( L );
|
||||
return 1;
|
||||
}
|
||||
|
||||
LunaScreenHowToPlay()
|
||||
{
|
||||
ADD_METHOD( GetLifeMeter );
|
||||
}
|
||||
};
|
||||
|
||||
LUA_REGISTER_DERIVED_CLASS( ScreenHowToPlay, ScreenAttract )
|
||||
// lua end
|
||||
|
||||
/*
|
||||
* (c) 2001-2004 Chris Danford, Thad Ward
|
||||
* 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.
|
||||
*/
|
||||
|
||||
+363
-362
@@ -1,362 +1,363 @@
|
||||
#include "global.h"
|
||||
#include "ScreenRanking.h"
|
||||
#include "ScreenManager.h"
|
||||
#include "SongManager.h"
|
||||
#include "GameState.h"
|
||||
#include "GameManager.h"
|
||||
#include "ProfileManager.h"
|
||||
#include "Profile.h"
|
||||
|
||||
|
||||
static const char *RankingTypeNames[] = {
|
||||
"Category",
|
||||
"Course",
|
||||
};
|
||||
XToString( RankingType );
|
||||
LuaXType( RankingType );
|
||||
|
||||
AutoScreenMessage( SM_ShowNextPage );
|
||||
AutoScreenMessage( SM_HidePage );
|
||||
|
||||
REGISTER_SCREEN_CLASS( ScreenRanking );
|
||||
|
||||
#define BULLET_X(row) (BULLET_START_X+ROW_SPACING_X*row)
|
||||
#define BULLET_Y(row) (BULLET_START_Y+ROW_SPACING_Y*row)
|
||||
#define NAME_X(row) (NAME_START_X+ROW_SPACING_X*row)
|
||||
#define NAME_Y(row) (NAME_START_Y+ROW_SPACING_Y*row)
|
||||
#define SCORE_X(row) (SCORE_START_X+ROW_SPACING_X*row)
|
||||
#define SCORE_Y(row) (SCORE_START_Y+ROW_SPACING_Y*row)
|
||||
#define POINTS_X(row) (POINTS_START_X+ROW_SPACING_X*row)
|
||||
#define POINTS_Y(row) (POINTS_START_Y+ROW_SPACING_Y*row)
|
||||
#define TIME_X(row) (TIME_START_X+ROW_SPACING_X*row)
|
||||
#define TIME_Y(row) (TIME_START_Y+ROW_SPACING_Y*row)
|
||||
|
||||
static RString STEPS_TYPE_COLOR_NAME( size_t i ) { return ssprintf("StepsTypeColor%d",int(i+1)); }
|
||||
|
||||
void ScreenRanking::Init()
|
||||
{
|
||||
STEPS_TYPES_TO_SHOW.Load( m_sName,"StepsTypesToHide" ); // tricky: The metric name is "hide" because ThemeMetricStepsTypesToShow takes a list of what to hide and returns what StepsTypes to show
|
||||
PAGE_FADE_SECONDS.Load ( m_sName,"PageFadeSeconds" );
|
||||
|
||||
ScreenAttract::Init();
|
||||
|
||||
m_textStepsType.SetName( "StepsType" );
|
||||
m_textStepsType.LoadFromFont( THEME->GetPathF(m_sName,"StepsType") );
|
||||
m_textStepsType.SetShadowLength( 0 );
|
||||
this->AddChild( &m_textStepsType );
|
||||
LOAD_ALL_COMMANDS( m_textStepsType );
|
||||
|
||||
|
||||
RANKING_TYPE.Load ( m_sName,"RankingType");
|
||||
COURSES_TO_SHOW.Load ( m_sName,"CoursesToShow");
|
||||
SECONDS_PER_PAGE.Load ( m_sName,"SecondsPerPage" );
|
||||
|
||||
NO_SCORE_NAME.Load( m_sName,"NoScoreName" );
|
||||
ROW_SPACING_X.Load( m_sName,"RowSpacingX" );
|
||||
ROW_SPACING_Y.Load( m_sName,"RowSpacingY" );
|
||||
BULLET_START_X.Load( m_sName, "BulletStartX" );
|
||||
BULLET_START_Y.Load( m_sName, "BulletStartY" );
|
||||
NAME_START_X.Load( m_sName, "NameStartX" );
|
||||
NAME_START_Y.Load( m_sName, "NameStartY" );
|
||||
SCORE_START_X.Load( m_sName, "ScoreStartX" );
|
||||
SCORE_START_Y.Load( m_sName, "ScoreStartY" );
|
||||
POINTS_START_X.Load( m_sName, "PointsStartX" );
|
||||
POINTS_START_Y.Load( m_sName, "PointsStartY" );
|
||||
TIME_START_X.Load( m_sName, "TimeStartX" );
|
||||
TIME_START_Y.Load( m_sName, "TimeStartY" );
|
||||
STEPS_TYPE_COLOR.Load( m_sName,STEPS_TYPE_COLOR_NAME,NUM_RANKING_LINES );
|
||||
|
||||
if( RANKING_TYPE == RankingType_Category )
|
||||
{
|
||||
m_textCategory.SetName( "Category" );
|
||||
m_textCategory.LoadFromFont( THEME->GetPathF(m_sName,"category") );
|
||||
//m_textCategory.SetShadowLength( 0 );
|
||||
this->AddChild( &m_textCategory );
|
||||
LOAD_ALL_COMMANDS( m_textCategory );
|
||||
|
||||
for( unsigned i=0; i<STEPS_TYPES_TO_SHOW.GetValue().size(); i++ )
|
||||
{
|
||||
for( int c=0; c<NUM_RankingCategory; c++ )
|
||||
{
|
||||
PageToShow pts;
|
||||
pts.colorIndex = i;
|
||||
pts.category = (RankingCategory)c;
|
||||
StepsType st = STEPS_TYPES_TO_SHOW.GetValue()[i];
|
||||
pts.aTypes.push_back( make_pair(Difficulty_Invalid, st) );
|
||||
m_vPagesToShow.push_back( pts );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( RANKING_TYPE == RankingType_SpecificTrail )
|
||||
{
|
||||
m_Banner.SetName( "Banner" );
|
||||
this->AddChild( &m_Banner );
|
||||
LOAD_ALL_COMMANDS( m_Banner );
|
||||
|
||||
m_textCourseTitle.SetName( "CourseTitle" );
|
||||
m_textCourseTitle.LoadFromFont( THEME->GetPathF(m_sName,"course title") );
|
||||
//m_textCourseTitle.SetShadowLength( 0 );
|
||||
this->AddChild( &m_textCourseTitle );
|
||||
LOAD_ALL_COMMANDS( m_textCourseTitle );
|
||||
|
||||
vector<RString> asCoursePaths;
|
||||
split( COURSES_TO_SHOW, ",", asCoursePaths, true );
|
||||
for( unsigned i=0; i<STEPS_TYPES_TO_SHOW.GetValue().size(); i++ )
|
||||
{
|
||||
for( unsigned c=0; c<asCoursePaths.size(); c++ )
|
||||
{
|
||||
PageToShow pts;
|
||||
pts.colorIndex = i;
|
||||
StepsType st = STEPS_TYPES_TO_SHOW.GetValue()[i];
|
||||
pts.aTypes.push_back( make_pair(Difficulty_Invalid, st) );
|
||||
pts.pCourse = SONGMAN->GetCourseFromPath( asCoursePaths[c] );
|
||||
if( pts.pCourse == NULL )
|
||||
continue;
|
||||
|
||||
pts.pTrail = pts.pCourse->GetTrail( st );
|
||||
if( pts.pTrail == NULL )
|
||||
continue;
|
||||
|
||||
m_vPagesToShow.push_back( pts );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( int l=0; l<NUM_RANKING_LINES; l++ )
|
||||
{
|
||||
m_sprBullets[l].Load( THEME->GetPathG( m_sName, ssprintf("bullets 1x%d",NUM_RANKING_LINES) ) );
|
||||
m_sprBullets[l]->SetName( ssprintf("Bullet%d",l+1) );
|
||||
m_sprBullets[l]->StopAnimating();
|
||||
m_sprBullets[l]->SetState( l );
|
||||
m_sprBullets[l]->SetXY( BULLET_X(l), BULLET_Y(l) );
|
||||
ActorUtil::LoadAllCommands( *m_sprBullets[l], m_sName );
|
||||
this->AddChild( m_sprBullets[l] );
|
||||
|
||||
m_textNames[l].SetName( ssprintf("Name%d",l+1) );
|
||||
m_textNames[l].LoadFromFont( THEME->GetPathF(m_sName,"name") );
|
||||
m_textNames[l].SetXY( NAME_X(l), NAME_Y(l) );
|
||||
ActorUtil::LoadAllCommands( m_textNames[l], m_sName );
|
||||
this->AddChild( &m_textNames[l] );
|
||||
|
||||
m_textScores[l].SetName( ssprintf("Score%d",l+1) );
|
||||
m_textScores[l].LoadFromFont( THEME->GetPathF(m_sName,"score") );
|
||||
m_textScores[l].SetXY( SCORE_X(l), SCORE_Y(l) );
|
||||
ActorUtil::LoadAllCommands( m_textScores[l], m_sName );
|
||||
this->AddChild( &m_textScores[l] );
|
||||
|
||||
m_textPoints[l].SetName( ssprintf("Points%d",l+1) );
|
||||
m_textPoints[l].LoadFromFont( THEME->GetPathF(m_sName,"points") );
|
||||
m_textPoints[l].SetVisible( false );
|
||||
m_textPoints[l].SetXY( POINTS_X(l), POINTS_Y(l) );
|
||||
ActorUtil::LoadAllCommands( m_textPoints[l], m_sName );
|
||||
this->AddChild( &m_textPoints[l] );
|
||||
|
||||
m_textTime[l].SetName( ssprintf("Time%d",l+1) );
|
||||
m_textTime[l].LoadFromFont( THEME->GetPathF(m_sName,"time") );
|
||||
m_textTime[l].SetVisible( false );
|
||||
m_textTime[l].SetXY( TIME_X(l), TIME_Y(l) );
|
||||
ActorUtil::LoadAllCommands( m_textTime[l], m_sName );
|
||||
this->AddChild( &m_textTime[l] );
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenRanking::BeginScreen()
|
||||
{
|
||||
m_iNextPageToShow = 0;
|
||||
|
||||
ScreenAttract::BeginScreen();
|
||||
|
||||
this->HandleScreenMessage( SM_ShowNextPage );
|
||||
}
|
||||
|
||||
void ScreenRanking::HandleScreenMessage( const ScreenMessage SM )
|
||||
{
|
||||
if( SM == SM_ShowNextPage )
|
||||
{
|
||||
if( m_iNextPageToShow < m_vPagesToShow.size() )
|
||||
{
|
||||
float fSecsToShow = SetPage( m_vPagesToShow[m_iNextPageToShow] );
|
||||
++m_iNextPageToShow;
|
||||
this->SortByDrawOrder();
|
||||
|
||||
this->PostScreenMessage( SM_HidePage, fSecsToShow-PAGE_FADE_SECONDS );
|
||||
}
|
||||
else
|
||||
{
|
||||
StartTransitioningScreen(SM_GoToNextScreen);
|
||||
}
|
||||
}
|
||||
else if( SM == SM_HidePage )
|
||||
{
|
||||
this->PlayCommand( "SwitchPage" );
|
||||
this->PostScreenMessage( SM_ShowNextPage, PAGE_FADE_SECONDS );
|
||||
}
|
||||
|
||||
ScreenAttract::HandleScreenMessage( SM );
|
||||
}
|
||||
|
||||
float ScreenRanking::SetPage( const PageToShow &pts )
|
||||
{
|
||||
// This is going to take a while to load. Possibly longer than one frame.
|
||||
// So, zero the next update so we don't skip.
|
||||
SCREENMAN->ZeroNextUpdate();
|
||||
|
||||
// init page
|
||||
StepsType st = pts.aTypes.front().second;
|
||||
m_textStepsType.SetText( GAMEMAN->GetStepsTypeInfo(st).GetLocalizedString() );
|
||||
|
||||
|
||||
bool bShowScores = false;
|
||||
bool bShowPoints = false;
|
||||
bool bShowTime = false;
|
||||
switch( RANKING_TYPE )
|
||||
{
|
||||
case RankingType_Category:
|
||||
bShowScores = true;
|
||||
break;
|
||||
case RankingType_SpecificTrail:
|
||||
bShowScores = !pts.pCourse->IsOni();
|
||||
bShowPoints = pts.pCourse->IsOni();
|
||||
bShowTime = pts.pCourse->IsOni();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
for( int l=0; l<NUM_RANKING_LINES; l++ )
|
||||
{
|
||||
m_textNames[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
m_textScores[l].SetVisible( bShowScores );
|
||||
m_textScores[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
m_textPoints[l].SetVisible( bShowPoints );
|
||||
m_textPoints[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
m_textTime[l].SetVisible( bShowTime );
|
||||
m_textTime[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
}
|
||||
|
||||
switch( RANKING_TYPE )
|
||||
{
|
||||
case RankingType_Category:
|
||||
{
|
||||
m_textCategory.SetText( ssprintf("Type %c", 'A'+pts.category) );
|
||||
|
||||
for( int l=0; l<NUM_RANKING_LINES; l++ )
|
||||
{
|
||||
// No need to shadow at this point.
|
||||
st = pts.aTypes.front().second;
|
||||
HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCategoryHighScoreList(st, pts.category);
|
||||
HighScore hs;
|
||||
bool bRecentHighScore = false;
|
||||
if( l < (int)hsl.vHighScores.size() )
|
||||
{
|
||||
hs = hsl.vHighScores[l];
|
||||
RString *psName = hsl.vHighScores[l].GetNameMutable();
|
||||
bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
hs.SetName( NO_SCORE_NAME );
|
||||
}
|
||||
|
||||
m_textNames[l].SetText( hs.GetDisplayName() );
|
||||
m_textScores[l].SetText( ssprintf("%09i",hs.GetScore()) );
|
||||
m_textNames[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
m_textScores[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
if( bRecentHighScore )
|
||||
{
|
||||
m_textNames[l].SetEffectGlowBlink(0.1f);
|
||||
m_textScores[l].SetEffectGlowBlink(0.1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_textNames[l].StopEffect();
|
||||
m_textScores[l].StopEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
return SECONDS_PER_PAGE;
|
||||
case RankingType_SpecificTrail:
|
||||
{
|
||||
m_textCourseTitle.SetText( pts.pCourse->GetDisplayFullTitle() );
|
||||
|
||||
m_Banner.LoadFromCourse( pts.pCourse );
|
||||
|
||||
const HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList( pts.pCourse, pts.pTrail );
|
||||
for( int l=0; l<NUM_RANKING_LINES; l++ )
|
||||
{
|
||||
HighScore hs;
|
||||
bool bRecentHighScore = false;
|
||||
if( l < (int)hsl.vHighScores.size() )
|
||||
{
|
||||
hs = hsl.vHighScores[l];
|
||||
const RString *psName = hsl.vHighScores[l].GetNameMutable();
|
||||
bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
hs.SetName( NO_SCORE_NAME );
|
||||
}
|
||||
|
||||
m_textNames[l].SetText( hs.GetDisplayName() );
|
||||
if( pts.pCourse->IsOni() )
|
||||
{
|
||||
m_textPoints[l].SetText( ssprintf("%04d",hs.GetScore()) );
|
||||
m_textTime[l].SetText( SecondsToMMSSMsMs(hs.GetSurviveSeconds()) );
|
||||
m_textScores[l].SetText( "" );
|
||||
} else {
|
||||
m_textPoints[l].SetText( "" );
|
||||
m_textTime[l].SetText( "" );
|
||||
m_textScores[l].SetText( ssprintf("%09d",hs.GetScore()) );
|
||||
}
|
||||
m_textNames[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
m_textPoints[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
m_textTime[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
m_textScores[l].SetDiffuse( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
if( bRecentHighScore )
|
||||
{
|
||||
m_textNames[l].SetEffectGlowBlink(0.1f);
|
||||
m_textScores[l].SetEffectGlowBlink(0.1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_textNames[l].StopEffect();
|
||||
m_textScores[l].StopEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
return SECONDS_PER_PAGE;
|
||||
default:
|
||||
ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (c) 2001-2007 Chris Danford, Glenn Maynard
|
||||
* 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.
|
||||
*/
|
||||
#include "global.h"
|
||||
#include "ScreenRanking.h"
|
||||
#include "ScreenManager.h"
|
||||
#include "SongManager.h"
|
||||
#include "GameState.h"
|
||||
#include "GameManager.h"
|
||||
#include "ProfileManager.h"
|
||||
#include "Profile.h"
|
||||
|
||||
|
||||
static const char *RankingTypeNames[] = {
|
||||
"Category",
|
||||
"Course",
|
||||
};
|
||||
XToString( RankingType );
|
||||
LuaXType( RankingType );
|
||||
|
||||
AutoScreenMessage( SM_ShowNextPage );
|
||||
AutoScreenMessage( SM_HidePage );
|
||||
|
||||
REGISTER_SCREEN_CLASS( ScreenRanking );
|
||||
|
||||
#define BULLET_X(row) (BULLET_START_X+ROW_SPACING_X*row)
|
||||
#define BULLET_Y(row) (BULLET_START_Y+ROW_SPACING_Y*row)
|
||||
#define NAME_X(row) (NAME_START_X+ROW_SPACING_X*row)
|
||||
#define NAME_Y(row) (NAME_START_Y+ROW_SPACING_Y*row)
|
||||
#define SCORE_X(row) (SCORE_START_X+ROW_SPACING_X*row)
|
||||
#define SCORE_Y(row) (SCORE_START_Y+ROW_SPACING_Y*row)
|
||||
#define POINTS_X(row) (POINTS_START_X+ROW_SPACING_X*row)
|
||||
#define POINTS_Y(row) (POINTS_START_Y+ROW_SPACING_Y*row)
|
||||
#define TIME_X(row) (TIME_START_X+ROW_SPACING_X*row)
|
||||
#define TIME_Y(row) (TIME_START_Y+ROW_SPACING_Y*row)
|
||||
|
||||
static RString STEPS_TYPE_COLOR_NAME( size_t i ) { return ssprintf("StepsTypeColor%d",int(i+1)); }
|
||||
|
||||
void ScreenRanking::Init()
|
||||
{
|
||||
STEPS_TYPES_TO_SHOW.Load( m_sName,"StepsTypesToHide" ); // tricky: The metric name is "hide" because ThemeMetricStepsTypesToShow takes a list of what to hide and returns what StepsTypes to show
|
||||
PAGE_FADE_SECONDS.Load ( m_sName,"PageFadeSeconds" );
|
||||
|
||||
ScreenAttract::Init();
|
||||
|
||||
m_textStepsType.SetName( "StepsType" );
|
||||
m_textStepsType.LoadFromFont( THEME->GetPathF(m_sName,"StepsType") );
|
||||
m_textStepsType.SetShadowLength( 0 );
|
||||
this->AddChild( &m_textStepsType );
|
||||
LOAD_ALL_COMMANDS( m_textStepsType );
|
||||
|
||||
|
||||
RANKING_TYPE.Load ( m_sName,"RankingType");
|
||||
COURSES_TO_SHOW.Load ( m_sName,"CoursesToShow");
|
||||
SECONDS_PER_PAGE.Load ( m_sName,"SecondsPerPage" );
|
||||
|
||||
NO_SCORE_NAME.Load( m_sName,"NoScoreName" );
|
||||
ROW_SPACING_X.Load( m_sName,"RowSpacingX" );
|
||||
ROW_SPACING_Y.Load( m_sName,"RowSpacingY" );
|
||||
BULLET_START_X.Load( m_sName, "BulletStartX" );
|
||||
BULLET_START_Y.Load( m_sName, "BulletStartY" );
|
||||
NAME_START_X.Load( m_sName, "NameStartX" );
|
||||
NAME_START_Y.Load( m_sName, "NameStartY" );
|
||||
SCORE_START_X.Load( m_sName, "ScoreStartX" );
|
||||
SCORE_START_Y.Load( m_sName, "ScoreStartY" );
|
||||
POINTS_START_X.Load( m_sName, "PointsStartX" );
|
||||
POINTS_START_Y.Load( m_sName, "PointsStartY" );
|
||||
TIME_START_X.Load( m_sName, "TimeStartX" );
|
||||
TIME_START_Y.Load( m_sName, "TimeStartY" );
|
||||
STEPS_TYPE_COLOR.Load( m_sName,STEPS_TYPE_COLOR_NAME,NUM_RANKING_LINES );
|
||||
|
||||
if( RANKING_TYPE == RankingType_Category )
|
||||
{
|
||||
m_textCategory.SetName( "Category" );
|
||||
m_textCategory.LoadFromFont( THEME->GetPathF(m_sName,"category") );
|
||||
//m_textCategory.SetShadowLength( 0 );
|
||||
this->AddChild( &m_textCategory );
|
||||
LOAD_ALL_COMMANDS( m_textCategory );
|
||||
|
||||
for( unsigned i=0; i<STEPS_TYPES_TO_SHOW.GetValue().size(); i++ )
|
||||
{
|
||||
for( int c=0; c<NUM_RankingCategory; c++ )
|
||||
{
|
||||
PageToShow pts;
|
||||
pts.colorIndex = i;
|
||||
pts.category = (RankingCategory)c;
|
||||
StepsType st = STEPS_TYPES_TO_SHOW.GetValue()[i];
|
||||
pts.aTypes.push_back( make_pair(Difficulty_Invalid, st) );
|
||||
m_vPagesToShow.push_back( pts );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( RANKING_TYPE == RankingType_SpecificTrail )
|
||||
{
|
||||
m_Banner.SetName( "Banner" );
|
||||
this->AddChild( &m_Banner );
|
||||
LOAD_ALL_COMMANDS( m_Banner );
|
||||
|
||||
m_textCourseTitle.SetName( "CourseTitle" );
|
||||
m_textCourseTitle.LoadFromFont( THEME->GetPathF(m_sName,"course title") );
|
||||
//m_textCourseTitle.SetShadowLength( 0 );
|
||||
this->AddChild( &m_textCourseTitle );
|
||||
LOAD_ALL_COMMANDS( m_textCourseTitle );
|
||||
|
||||
vector<RString> asCoursePaths;
|
||||
split( COURSES_TO_SHOW, ",", asCoursePaths, true );
|
||||
for( unsigned i=0; i<STEPS_TYPES_TO_SHOW.GetValue().size(); i++ )
|
||||
{
|
||||
for( unsigned c=0; c<asCoursePaths.size(); c++ )
|
||||
{
|
||||
PageToShow pts;
|
||||
pts.colorIndex = i;
|
||||
StepsType st = STEPS_TYPES_TO_SHOW.GetValue()[i];
|
||||
pts.aTypes.push_back( make_pair(Difficulty_Invalid, st) );
|
||||
pts.pCourse = SONGMAN->GetCourseFromPath( asCoursePaths[c] );
|
||||
if( pts.pCourse == NULL )
|
||||
continue;
|
||||
|
||||
pts.pTrail = pts.pCourse->GetTrail( st );
|
||||
if( pts.pTrail == NULL )
|
||||
continue;
|
||||
|
||||
m_vPagesToShow.push_back( pts );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( int l=0; l<NUM_RANKING_LINES; l++ )
|
||||
{
|
||||
m_sprBullets[l].Load( THEME->GetPathG( m_sName, ssprintf("bullets 1x%d",NUM_RANKING_LINES) ) );
|
||||
m_sprBullets[l]->SetName( ssprintf("Bullet%d",l+1) );
|
||||
m_sprBullets[l]->StopAnimating();
|
||||
m_sprBullets[l]->SetState( l );
|
||||
m_sprBullets[l]->SetXY( BULLET_X(l), BULLET_Y(l) );
|
||||
ActorUtil::LoadAllCommands( *m_sprBullets[l], m_sName );
|
||||
this->AddChild( m_sprBullets[l] );
|
||||
|
||||
m_textNames[l].SetName( ssprintf("Name%d",l+1) );
|
||||
m_textNames[l].LoadFromFont( THEME->GetPathF(m_sName,"name") );
|
||||
m_textNames[l].SetXY( NAME_X(l), NAME_Y(l) );
|
||||
ActorUtil::LoadAllCommands( m_textNames[l], m_sName );
|
||||
this->AddChild( &m_textNames[l] );
|
||||
|
||||
m_textScores[l].SetName( ssprintf("Score%d",l+1) );
|
||||
m_textScores[l].LoadFromFont( THEME->GetPathF(m_sName,"score") );
|
||||
m_textScores[l].SetXY( SCORE_X(l), SCORE_Y(l) );
|
||||
ActorUtil::LoadAllCommands( m_textScores[l], m_sName );
|
||||
this->AddChild( &m_textScores[l] );
|
||||
|
||||
m_textPoints[l].SetName( ssprintf("Points%d",l+1) );
|
||||
m_textPoints[l].LoadFromFont( THEME->GetPathF(m_sName,"points") );
|
||||
m_textPoints[l].SetVisible( false );
|
||||
m_textPoints[l].SetXY( POINTS_X(l), POINTS_Y(l) );
|
||||
ActorUtil::LoadAllCommands( m_textPoints[l], m_sName );
|
||||
this->AddChild( &m_textPoints[l] );
|
||||
|
||||
m_textTime[l].SetName( ssprintf("Time%d",l+1) );
|
||||
m_textTime[l].LoadFromFont( THEME->GetPathF(m_sName,"time") );
|
||||
m_textTime[l].SetVisible( false );
|
||||
m_textTime[l].SetXY( TIME_X(l), TIME_Y(l) );
|
||||
ActorUtil::LoadAllCommands( m_textTime[l], m_sName );
|
||||
this->AddChild( &m_textTime[l] );
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenRanking::BeginScreen()
|
||||
{
|
||||
m_iNextPageToShow = 0;
|
||||
|
||||
ScreenAttract::BeginScreen();
|
||||
|
||||
this->HandleScreenMessage( SM_ShowNextPage );
|
||||
}
|
||||
|
||||
void ScreenRanking::HandleScreenMessage( const ScreenMessage SM )
|
||||
{
|
||||
if( SM == SM_ShowNextPage )
|
||||
{
|
||||
if( m_iNextPageToShow < m_vPagesToShow.size() )
|
||||
{
|
||||
float fSecsToShow = SetPage( m_vPagesToShow[m_iNextPageToShow] );
|
||||
++m_iNextPageToShow;
|
||||
this->SortByDrawOrder();
|
||||
|
||||
this->PlayCommand( "NextPage" );
|
||||
this->PostScreenMessage( SM_HidePage, fSecsToShow-PAGE_FADE_SECONDS );
|
||||
}
|
||||
else
|
||||
{
|
||||
StartTransitioningScreen(SM_GoToNextScreen);
|
||||
}
|
||||
}
|
||||
else if( SM == SM_HidePage )
|
||||
{
|
||||
this->PlayCommand( "SwitchedPage" );
|
||||
this->PostScreenMessage( SM_ShowNextPage, PAGE_FADE_SECONDS );
|
||||
}
|
||||
|
||||
ScreenAttract::HandleScreenMessage( SM );
|
||||
}
|
||||
|
||||
float ScreenRanking::SetPage( const PageToShow &pts )
|
||||
{
|
||||
// This is going to take a while to load. Possibly longer than one frame.
|
||||
// So, zero the next update so we don't skip.
|
||||
SCREENMAN->ZeroNextUpdate();
|
||||
|
||||
// init page
|
||||
StepsType st = pts.aTypes.front().second;
|
||||
m_textStepsType.SetText( GAMEMAN->GetStepsTypeInfo(st).GetLocalizedString() );
|
||||
|
||||
|
||||
bool bShowScores = false;
|
||||
bool bShowPoints = false;
|
||||
bool bShowTime = false;
|
||||
switch( RANKING_TYPE )
|
||||
{
|
||||
case RankingType_Category:
|
||||
bShowScores = true;
|
||||
break;
|
||||
case RankingType_SpecificTrail:
|
||||
bShowScores = !pts.pCourse->IsOni();
|
||||
bShowPoints = pts.pCourse->IsOni();
|
||||
bShowTime = pts.pCourse->IsOni();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
for( int l=0; l<NUM_RANKING_LINES; l++ )
|
||||
{
|
||||
m_textNames[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
m_textScores[l].SetVisible( bShowScores );
|
||||
m_textScores[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
m_textPoints[l].SetVisible( bShowPoints );
|
||||
m_textPoints[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
m_textTime[l].SetVisible( bShowTime );
|
||||
m_textTime[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
}
|
||||
|
||||
switch( RANKING_TYPE )
|
||||
{
|
||||
case RankingType_Category:
|
||||
{
|
||||
m_textCategory.SetText( ssprintf("Type %c", 'A'+pts.category) );
|
||||
|
||||
for( int l=0; l<NUM_RANKING_LINES; l++ )
|
||||
{
|
||||
// No need to shadow at this point.
|
||||
st = pts.aTypes.front().second;
|
||||
HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCategoryHighScoreList(st, pts.category);
|
||||
HighScore hs;
|
||||
bool bRecentHighScore = false;
|
||||
if( l < (int)hsl.vHighScores.size() )
|
||||
{
|
||||
hs = hsl.vHighScores[l];
|
||||
RString *psName = hsl.vHighScores[l].GetNameMutable();
|
||||
bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
hs.SetName( NO_SCORE_NAME );
|
||||
}
|
||||
|
||||
m_textNames[l].SetText( hs.GetDisplayName() );
|
||||
m_textScores[l].SetText( ssprintf("%09i",hs.GetScore()) );
|
||||
m_textNames[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
m_textScores[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
if( bRecentHighScore )
|
||||
{
|
||||
m_textNames[l].SetEffectGlowBlink(0.1f);
|
||||
m_textScores[l].SetEffectGlowBlink(0.1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_textNames[l].StopEffect();
|
||||
m_textScores[l].StopEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
return SECONDS_PER_PAGE;
|
||||
case RankingType_SpecificTrail:
|
||||
{
|
||||
m_textCourseTitle.SetText( pts.pCourse->GetDisplayFullTitle() );
|
||||
|
||||
m_Banner.LoadFromCourse( pts.pCourse );
|
||||
|
||||
const HighScoreList &hsl = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList( pts.pCourse, pts.pTrail );
|
||||
for( int l=0; l<NUM_RANKING_LINES; l++ )
|
||||
{
|
||||
HighScore hs;
|
||||
bool bRecentHighScore = false;
|
||||
if( l < (int)hsl.vHighScores.size() )
|
||||
{
|
||||
hs = hsl.vHighScores[l];
|
||||
const RString *psName = hsl.vHighScores[l].GetNameMutable();
|
||||
bRecentHighScore = find( GAMESTATE->m_vpsNamesThatWereFilled.begin(), GAMESTATE->m_vpsNamesThatWereFilled.end(), psName ) != GAMESTATE->m_vpsNamesThatWereFilled.end();
|
||||
}
|
||||
else
|
||||
{
|
||||
hs.SetName( NO_SCORE_NAME );
|
||||
}
|
||||
|
||||
m_textNames[l].SetText( hs.GetDisplayName() );
|
||||
if( pts.pCourse->IsOni() )
|
||||
{
|
||||
m_textPoints[l].SetText( ssprintf("%04d",hs.GetScore()) );
|
||||
m_textTime[l].SetText( SecondsToMMSSMsMs(hs.GetSurviveSeconds()) );
|
||||
m_textScores[l].SetText( "" );
|
||||
} else {
|
||||
m_textPoints[l].SetText( "" );
|
||||
m_textTime[l].SetText( "" );
|
||||
m_textScores[l].SetText( ssprintf("%09d",hs.GetScore()) );
|
||||
}
|
||||
m_textNames[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
m_textPoints[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
m_textTime[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
m_textScores[l].SetDiffuseColor( STEPS_TYPE_COLOR.GetValue(pts.colorIndex) );
|
||||
|
||||
if( bRecentHighScore )
|
||||
{
|
||||
m_textNames[l].SetEffectGlowBlink(0.1f);
|
||||
m_textScores[l].SetEffectGlowBlink(0.1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_textNames[l].StopEffect();
|
||||
m_textScores[l].StopEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
return SECONDS_PER_PAGE;
|
||||
default:
|
||||
ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (c) 2001-2007 Chris Danford, Glenn Maynard
|
||||
* 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.
|
||||
*/
|
||||
|
||||
+2045
-2038
File diff suppressed because it is too large
Load Diff
+479
-475
@@ -1,475 +1,479 @@
|
||||
#ifndef SONG_H
|
||||
#define SONG_H
|
||||
|
||||
#include "Attack.h"
|
||||
#include "TimingData.h"
|
||||
#include "Difficulty.h"
|
||||
#include "EnumHelper.h"
|
||||
#include "RageUtil_AutoPtr.h"
|
||||
#include "RageUtil_CachedObject.h"
|
||||
#include "RageTypes.h"
|
||||
#include "Steps.h"
|
||||
#include <set>
|
||||
|
||||
class Style;
|
||||
class StepsID;
|
||||
struct lua_State;
|
||||
struct BackgroundChange;
|
||||
|
||||
void FixupPath( RString &path, const RString &sSongPath );
|
||||
RString GetSongAssetPath( RString sPath, const RString &sSongPath );
|
||||
|
||||
/** @brief The version of the .ssc file format. */
|
||||
const static float STEPFILE_VERSION_NUMBER = 0.81f;
|
||||
|
||||
/** @brief How many edits for this song can each profile have? */
|
||||
const int MAX_EDITS_PER_SONG_PER_PROFILE = 15;
|
||||
/** @brief How many edits for this song can be available? */
|
||||
const int MAX_EDITS_PER_SONG = MAX_EDITS_PER_SONG_PER_PROFILE * NUM_ProfileSlot;
|
||||
|
||||
extern const int FILE_CACHE_VERSION;
|
||||
|
||||
/** @brief The different background layers available. */
|
||||
enum BackgroundLayer
|
||||
{
|
||||
BACKGROUND_LAYER_1,
|
||||
BACKGROUND_LAYER_2,
|
||||
//BACKGROUND_LAYER_3, // StepCollection get
|
||||
NUM_BackgroundLayer,
|
||||
BACKGROUND_LAYER_Invalid
|
||||
};
|
||||
|
||||
/** @brief A custom foreach loop for the different background layers. */
|
||||
#define FOREACH_BackgroundLayer( bl ) FOREACH_ENUM( BackgroundLayer, bl )
|
||||
|
||||
/** @brief Different instrument tracks for band type games. */
|
||||
enum InstrumentTrack
|
||||
{
|
||||
InstrumentTrack_Guitar,
|
||||
InstrumentTrack_Rhythm,
|
||||
InstrumentTrack_Bass,
|
||||
NUM_InstrumentTrack,
|
||||
InstrumentTrack_Invalid
|
||||
};
|
||||
const RString& InstrumentTrackToString( InstrumentTrack it );
|
||||
InstrumentTrack StringToInstrumentTrack( const RString& s );
|
||||
|
||||
/** @brief The collection of lyrics for the Song. */
|
||||
struct LyricSegment
|
||||
{
|
||||
float m_fStartTime; /** @brief When does the lyric show up? */
|
||||
RString m_sLyric; /** @brief The lyrics themselves. */
|
||||
RageColor m_Color; /** @brief The color of the lyrics. */
|
||||
};
|
||||
|
||||
/** @brief Holds all music metadata and steps for one song. */
|
||||
class Song
|
||||
{
|
||||
RString m_sSongDir;
|
||||
public:
|
||||
void SetSongDir( const RString sDir ) { m_sSongDir = sDir; }
|
||||
RString GetSongDir() { return m_sSongDir; }
|
||||
|
||||
/** @brief When should this song be displayed in the music wheel? */
|
||||
enum SelectionDisplay
|
||||
{
|
||||
SHOW_ALWAYS, /**< always show on the wheel. */
|
||||
SHOW_NEVER /**< never show on the wheel (unless song hiding is turned off). */
|
||||
} m_SelectionDisplay;
|
||||
|
||||
Song();
|
||||
~Song();
|
||||
void Reset();
|
||||
void DetachSteps();
|
||||
|
||||
/**
|
||||
* @brief Load a song from the chosen directory.
|
||||
*
|
||||
* This assumes that there is no song present right now.
|
||||
* @param sDir the song directory from which to load. */
|
||||
bool LoadFromSongDir( RString sDir );
|
||||
// This one takes the effort to reuse Steps pointers as best as it can
|
||||
bool ReloadFromSongDir( RString sDir );
|
||||
|
||||
/**
|
||||
* @brief Call this after loading a song to clean up invalid data.
|
||||
* @param fromCache was this data loaded from the cache file?
|
||||
* @param duringCache was this data loaded during the cache process? */
|
||||
void TidyUpData( bool fromCache = false, bool duringCache = false );
|
||||
|
||||
/**
|
||||
* @brief Get the new radar values, and determine the last second at the same time.
|
||||
* This is called by TidyUpData, after saving the Song.
|
||||
* @param fromCache was this data loaded from the cache file?
|
||||
* @param duringCache was this data loaded during the cache process? */
|
||||
void ReCalculateRadarValuesAndLastSecond(bool fromCache = false, bool duringCache = false);
|
||||
/**
|
||||
* @brief Translate any titles that aren't in english.
|
||||
* This is called by TidyUpData. */
|
||||
void TranslateTitles();
|
||||
|
||||
/**
|
||||
* @brief Save to the new SSC file format.
|
||||
* @param sPath the path where we're saving the file.
|
||||
* @param bSavingCache a flag to determine if we're saving cache data.
|
||||
*/
|
||||
bool SaveToSSCFile( RString sPath, bool bSavingCache );
|
||||
/** @brief Save to the SSC and SM files no matter what. */
|
||||
void Save();
|
||||
/**
|
||||
* @brief Save the current Song to a cache file using the preferred format.
|
||||
* @return its success or failure. */
|
||||
bool SaveToCacheFile();
|
||||
/**
|
||||
* @brief Save the current Song to a SM file.
|
||||
* @return its success or failure. */
|
||||
bool SaveToSMFile();
|
||||
/**
|
||||
* @brief Save the current Song to a DWI file if possible.
|
||||
* @return its success or failure. */
|
||||
bool SaveToDWIFile();
|
||||
|
||||
const RString &GetSongFilePath() const;
|
||||
RString GetCacheFilePath() const;
|
||||
|
||||
void AddAutoGenNotes();
|
||||
/**
|
||||
* @brief Automatically generate steps from one type to another.
|
||||
* @param ntTo the StepsType we're making.
|
||||
* @param ntFrom the StepsType we're generating from.
|
||||
*/
|
||||
void AutoGen( StepsType ntTo, StepsType ntFrom );
|
||||
void RemoveAutoGenNotes();
|
||||
|
||||
// Directory this song data came from:
|
||||
const RString &GetSongDir() const { return m_sSongDir; }
|
||||
|
||||
/**
|
||||
* @brief Filename associated with this file.
|
||||
* This will always have a .SSC extension. If we loaded a .SSC, this will
|
||||
* point to it, but if we loaded any other type, this will point to
|
||||
* a generated .SSC filename. */
|
||||
RString m_sSongFileName;
|
||||
|
||||
/** @brief The group this Song is in. */
|
||||
RString m_sGroupName;
|
||||
|
||||
/**
|
||||
* @brief the Profile this came from.
|
||||
* This is ProfileSlot_Invalid if it wasn't loaded from a profile. */
|
||||
ProfileSlot m_LoadedFromProfile;
|
||||
/** @brief Is the song file itself a symlink to another file? */
|
||||
bool m_bIsSymLink;
|
||||
bool m_bEnabled;
|
||||
|
||||
/** @brief The title of the Song. */
|
||||
RString m_sMainTitle;
|
||||
/** @brief The subtitle of the Song, if it exists. */
|
||||
RString m_sSubTitle;
|
||||
/** @brief The artist of the Song, if it exists. */
|
||||
RString m_sArtist;
|
||||
/** @brief The transliterated title of the Song, if it exists. */
|
||||
RString m_sMainTitleTranslit;
|
||||
/** @brief The transliterated subtitle of the Song, if it exists. */
|
||||
RString m_sSubTitleTranslit;
|
||||
/** @brief The transliterated artist of the Song, if it exists. */
|
||||
RString m_sArtistTranslit;
|
||||
|
||||
/* If PREFSMAN->m_bShowNative is off, these are the same as GetTranslit*
|
||||
* below. Otherwise, they return the main titles. */
|
||||
RString GetDisplayMainTitle() const;
|
||||
RString GetDisplaySubTitle() const;
|
||||
RString GetDisplayArtist() const;
|
||||
|
||||
/**
|
||||
* @brief Retrieve the transliterated title, or the main title if there is no translit.
|
||||
* @return the proper title. */
|
||||
RString GetTranslitMainTitle() const
|
||||
{
|
||||
return m_sMainTitleTranslit.size()? m_sMainTitleTranslit: m_sMainTitle;
|
||||
}
|
||||
/**
|
||||
* @brief Retrieve the transliterated subtitle, or the main subtitle if there is no translit.
|
||||
* @return the proper subtitle. */
|
||||
RString GetTranslitSubTitle() const
|
||||
{
|
||||
return m_sSubTitleTranslit.size()? m_sSubTitleTranslit: m_sSubTitle;
|
||||
}
|
||||
/**
|
||||
* @brief Retrieve the transliterated artist, or the main artist if there is no translit.
|
||||
* @return the proper artist. */
|
||||
RString GetTranslitArtist() const
|
||||
{
|
||||
return m_sArtistTranslit.size()? m_sArtistTranslit:m_sArtist;
|
||||
}
|
||||
|
||||
// "title subtitle"
|
||||
RString GetDisplayFullTitle() const;
|
||||
RString GetTranslitFullTitle() const;
|
||||
|
||||
/** @brief The version of the song/file. */
|
||||
float m_fVersion;
|
||||
/** @brief The genre of the song/file. */
|
||||
RString m_sGenre;
|
||||
|
||||
/**
|
||||
* @brief The person who worked with the song file who should be credited.
|
||||
* This is read and saved, but never actually used. */
|
||||
RString m_sCredit;
|
||||
|
||||
RString m_sOrigin; // song origin (for .ssc format)
|
||||
|
||||
RString m_sMusicFile;
|
||||
RString m_sInstrumentTrackFile[NUM_InstrumentTrack];
|
||||
|
||||
/** @brief The length of the music file. */
|
||||
float m_fMusicLengthSeconds;
|
||||
float m_fMusicSampleStartSeconds;
|
||||
float m_fMusicSampleLengthSeconds;
|
||||
DisplayBPM m_DisplayBPMType;
|
||||
float m_fSpecifiedBPMMin;
|
||||
float m_fSpecifiedBPMMax; // if a range, then Min != Max
|
||||
|
||||
RString m_sBannerFile; // typically a 16:5 ratio graphic (e.g. 256x80)
|
||||
RString m_sJacketFile; // typically square (e.g. 192x192, 256x256)
|
||||
RString m_sCDFile; // square (e.g. 128x128 [DDR 1st-3rd])
|
||||
RString m_sDiscFile; // rectangular (e.g. 256x192 [Pump], 200x150 [MGD3])
|
||||
/** @brief The location of the lyrics file, if it exists. */
|
||||
RString m_sLyricsFile;
|
||||
RString m_sBackgroundFile;
|
||||
RString m_sCDTitleFile;
|
||||
RString m_sPreviewVidFile;
|
||||
|
||||
AttackArray m_Attacks;
|
||||
vector<RString> m_sAttackString;
|
||||
|
||||
RString GetMusicPath() const;
|
||||
RString GetInstrumentTrackPath( InstrumentTrack it ) const;
|
||||
RString GetBannerPath() const;
|
||||
RString GetJacketPath() const;
|
||||
RString GetCDImagePath() const;
|
||||
RString GetDiscPath() const;
|
||||
RString GetLyricsPath() const;
|
||||
RString GetBackgroundPath() const;
|
||||
RString GetCDTitlePath() const;
|
||||
RString GetPreviewVidPath() const;
|
||||
|
||||
// For loading only:
|
||||
bool m_bHasMusic, m_bHasBanner, m_bHasBackground;
|
||||
|
||||
bool HasMusic() const;
|
||||
bool HasInstrumentTrack( InstrumentTrack it ) const;
|
||||
/**
|
||||
* @brief Does this song have a banner?
|
||||
* @return true if it does, false otherwise. */
|
||||
bool HasBanner() const;
|
||||
/**
|
||||
* @brief Does this song have a background image?
|
||||
* @return true if it does, false otherwise. */
|
||||
bool HasBackground() const;
|
||||
bool HasJacket() const;
|
||||
bool HasCDImage() const;
|
||||
bool HasDisc() const;
|
||||
bool HasCDTitle() const;
|
||||
//bool HasMovieBackground() const;
|
||||
bool HasBGChanges() const;
|
||||
bool HasLyrics() const;
|
||||
bool HasAttacks() const;
|
||||
bool HasPreviewVid() const;
|
||||
|
||||
bool Matches(RString sGroup, RString sSong) const;
|
||||
|
||||
/** @brief The Song's TimingData. */
|
||||
TimingData m_SongTiming;
|
||||
|
||||
float GetFirstBeat() const;
|
||||
float GetFirstSecond() const;
|
||||
float GetLastBeat() const;
|
||||
float GetLastSecond() const;
|
||||
float GetSpecifiedLastBeat() const;
|
||||
float GetSpecifiedLastSecond() const;
|
||||
|
||||
void SetFirstSecond(const float f);
|
||||
void SetLastSecond(const float f);
|
||||
void SetSpecifiedLastSecond(const float f);
|
||||
|
||||
typedef vector<BackgroundChange> VBackgroundChange;
|
||||
private:
|
||||
/** @brief The first second that a note is hit. */
|
||||
float firstSecond;
|
||||
/** @brief The last second that a note is hit. */
|
||||
float lastSecond;
|
||||
/** @brief The last second of the song for playing purposes. */
|
||||
float specifiedLastSecond;
|
||||
/**
|
||||
* @brief The background changes (sorted by layer) that are for this Song.
|
||||
* This uses an AutoPtr instead of a raw pointer so that the
|
||||
* auto gen'd copy constructor works correctly.
|
||||
* This must be sorted before gameplay. */
|
||||
AutoPtrCopyOnWrite<VBackgroundChange> m_BackgroundChanges[NUM_BackgroundLayer];
|
||||
/**
|
||||
* @brief The foreground changes that are for this Song.
|
||||
* This uses an AutoPtr instead of a raw pointer so that the
|
||||
* auto gen'd copy constructor works correctly.
|
||||
* This must be sorted before gameplay. */
|
||||
AutoPtrCopyOnWrite<VBackgroundChange> m_ForegroundChanges;
|
||||
|
||||
vector<RString> GetChangesToVectorString(const vector<BackgroundChange> & changes) const;
|
||||
public:
|
||||
const vector<BackgroundChange> &GetBackgroundChanges( BackgroundLayer bl ) const;
|
||||
vector<BackgroundChange> &GetBackgroundChanges( BackgroundLayer bl );
|
||||
const vector<BackgroundChange> &GetForegroundChanges() const;
|
||||
vector<BackgroundChange> &GetForegroundChanges();
|
||||
|
||||
vector<RString> GetBGChanges1ToVectorString() const;
|
||||
vector<RString> GetBGChanges2ToVectorString() const;
|
||||
vector<RString> GetFGChanges1ToVectorString() const;
|
||||
|
||||
vector<RString> GetInstrumentTracksToVectorString() const;
|
||||
|
||||
/**
|
||||
* @brief The list of LyricSegments.
|
||||
* This must be sorted before gameplay. */
|
||||
vector<LyricSegment> m_LyricSegments;
|
||||
|
||||
/* [splittiming]
|
||||
void AddBPMSegment( const BPMSegment &seg ) { m_Timing.AddBPMSegment( seg ); }
|
||||
void AddStopSegment( const StopSegment &seg ) { m_Timing.AddStopSegment( seg ); }
|
||||
void AddWarpSegment( const WarpSegment &seg ) { m_Timing.AddWarpSegment( seg ); }
|
||||
*/
|
||||
void AddBackgroundChange( BackgroundLayer blLayer, BackgroundChange seg );
|
||||
void AddForegroundChange( BackgroundChange seg );
|
||||
void AddLyricSegment( LyricSegment seg );
|
||||
|
||||
void GetDisplayBpms( DisplayBpms &AddTo ) const;
|
||||
const BackgroundChange &GetBackgroundAtBeat( BackgroundLayer iLayer, float fBeat ) const;
|
||||
|
||||
/* [splittiming]
|
||||
float GetBPMAtBeat( float fBeat ) const { return m_Timing.GetBPMAtBeat( fBeat ); }
|
||||
void SetBPMAtBeat( float fBeat, float fBPM ) { m_Timing.SetBPMAtBeat( fBeat, fBPM ); }
|
||||
BPMSegment& GetBPMSegmentAtBeat( float fBeat ) { return m_Timing.GetBPMSegmentAtBeat( fBeat ); }
|
||||
*/
|
||||
|
||||
Steps *CreateSteps();
|
||||
void InitSteps(Steps *pSteps);
|
||||
|
||||
/* [splittiming]
|
||||
float SongGetBeatFromElapsedTime( float fElapsedTime ) const
|
||||
{
|
||||
return m_SongTiming.GetBeatFromElapsedTime( fElapsedTime );
|
||||
}
|
||||
float StepsGetBeatFromElapsedTime( float fElapsedTime, const Steps &steps ) const
|
||||
{
|
||||
return steps.m_Timing.GetBeatFromElapsedTime( fElapsedTime );
|
||||
}
|
||||
|
||||
float SongGetElapsedTimeFromBeat( float fBeat ) const
|
||||
{
|
||||
return m_SongTiming.GetElapsedTimeFromBeat( fBeat );
|
||||
}
|
||||
float StepsGetElapsedTimeFromBeat( float fBeat, const Steps &steps ) const
|
||||
{
|
||||
return steps.m_Timing.GetElapsedTimeFromBeat( fBeat );
|
||||
}
|
||||
*/
|
||||
|
||||
/* [splittiming]
|
||||
float GetBeatFromElapsedTime( float fElapsedTime ) const
|
||||
{
|
||||
return m_Timing.GetBeatFromElapsedTime( fElapsedTime );
|
||||
}
|
||||
float GetElapsedTimeFromBeat( float fBeat ) const { return m_Timing.GetElapsedTimeFromBeat( fBeat ); }
|
||||
*/
|
||||
|
||||
bool HasSignificantBpmChangesOrStops() const;
|
||||
float GetStepsSeconds() const;
|
||||
bool IsLong() const;
|
||||
bool IsMarathon() const;
|
||||
|
||||
bool SongCompleteForStyle( const Style *st ) const;
|
||||
bool HasStepsType( StepsType st ) const;
|
||||
bool HasStepsTypeAndDifficulty( StepsType st, Difficulty dc ) const;
|
||||
const vector<Steps*>& GetAllSteps() const { return m_vpSteps; }
|
||||
const vector<Steps*>& GetStepsByStepsType( StepsType st ) const { return m_vpStepsByType[st]; }
|
||||
bool IsEasy( StepsType st ) const;
|
||||
bool IsTutorial() const;
|
||||
bool HasEdits( StepsType st ) const;
|
||||
|
||||
void SetEnabled( bool b ) { m_bEnabled = b; }
|
||||
bool GetEnabled() const { return m_bEnabled; }
|
||||
/**
|
||||
* @brief Determine if the song should be shown on the MusicWheel normally.
|
||||
* Songs that are not displayed normally may still be available during
|
||||
* random selection, extra stages, or other special conditions.
|
||||
* @return true if displayed normally, false otherwise. */
|
||||
bool NormallyDisplayed() const;
|
||||
bool ShowInDemonstrationAndRanking() const;
|
||||
|
||||
/**
|
||||
* @brief Add the chosen Steps to the Song.
|
||||
* We are responsible for deleting the memory pointed to by pSteps!
|
||||
* @param pSteps the new steps. */
|
||||
void AddSteps( Steps* pSteps );
|
||||
void DeleteSteps( const Steps* pSteps, bool bReAutoGen = true );
|
||||
|
||||
void FreeAllLoadedFromProfile( ProfileSlot slot = ProfileSlot_Invalid, const set<Steps*> *setInUse = NULL );
|
||||
bool WasLoadedFromProfile() const { return m_LoadedFromProfile != ProfileSlot_Invalid; }
|
||||
void GetStepsLoadedFromProfile( ProfileSlot slot, vector<Steps*> &vpStepsOut ) const;
|
||||
int GetNumStepsLoadedFromProfile( ProfileSlot slot ) const;
|
||||
bool IsEditAlreadyLoaded( Steps* pSteps ) const;
|
||||
|
||||
bool IsStepsUsingDifferentTiming(Steps *pSteps ) const;
|
||||
|
||||
/**
|
||||
* @brief An array of keysound file names (e.g. "beep.wav").
|
||||
* The index in this array corresponds to the index in TapNote.
|
||||
* If you change the index in here, you must change all NoteData too.
|
||||
* Any note that doesn't have a value in the range of this array
|
||||
* means "this note doesn't have a keysound". */
|
||||
vector<RString> m_vsKeysoundFile;
|
||||
|
||||
CachedObject<Song> m_CachedObject;
|
||||
|
||||
RString GetAttackString() const
|
||||
{
|
||||
return join(":", this->m_sAttackString);
|
||||
}
|
||||
|
||||
// Lua
|
||||
void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
/** @brief the Steps that belong to this Song. */
|
||||
vector<Steps*> m_vpSteps;
|
||||
/** @brief the Steps of a particular StepsType that belong to this Song. */
|
||||
vector<Steps*> m_vpStepsByType[NUM_StepsType];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @author Chris Danford, Glenn Maynard (c) 2001-2004
|
||||
* @section LICENSE
|
||||
* 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.
|
||||
*/
|
||||
#ifndef SONG_H
|
||||
#define SONG_H
|
||||
|
||||
#include "Attack.h"
|
||||
#include "TimingData.h"
|
||||
#include "Difficulty.h"
|
||||
#include "EnumHelper.h"
|
||||
#include "RageUtil_AutoPtr.h"
|
||||
#include "RageUtil_CachedObject.h"
|
||||
#include "RageTypes.h"
|
||||
#include "Steps.h"
|
||||
#include <set>
|
||||
|
||||
class Style;
|
||||
class StepsID;
|
||||
struct lua_State;
|
||||
struct BackgroundChange;
|
||||
|
||||
void FixupPath( RString &path, const RString &sSongPath );
|
||||
RString GetSongAssetPath( RString sPath, const RString &sSongPath );
|
||||
|
||||
/** @brief The version of the .ssc file format. */
|
||||
const static float STEPFILE_VERSION_NUMBER = 0.81f;
|
||||
|
||||
/** @brief How many edits for this song can each profile have? */
|
||||
const int MAX_EDITS_PER_SONG_PER_PROFILE = 15;
|
||||
/** @brief How many edits for this song can be available? */
|
||||
const int MAX_EDITS_PER_SONG = MAX_EDITS_PER_SONG_PER_PROFILE * NUM_ProfileSlot;
|
||||
|
||||
extern const int FILE_CACHE_VERSION;
|
||||
|
||||
/** @brief The different background layers available. */
|
||||
enum BackgroundLayer
|
||||
{
|
||||
BACKGROUND_LAYER_1,
|
||||
BACKGROUND_LAYER_2,
|
||||
//BACKGROUND_LAYER_3, // StepCollection get
|
||||
NUM_BackgroundLayer,
|
||||
BACKGROUND_LAYER_Invalid
|
||||
};
|
||||
|
||||
/** @brief A custom foreach loop for the different background layers. */
|
||||
#define FOREACH_BackgroundLayer( bl ) FOREACH_ENUM( BackgroundLayer, bl )
|
||||
|
||||
/** @brief Different instrument tracks for band type games. */
|
||||
enum InstrumentTrack
|
||||
{
|
||||
InstrumentTrack_Guitar,
|
||||
InstrumentTrack_Rhythm,
|
||||
InstrumentTrack_Bass,
|
||||
NUM_InstrumentTrack,
|
||||
InstrumentTrack_Invalid
|
||||
};
|
||||
const RString& InstrumentTrackToString( InstrumentTrack it );
|
||||
InstrumentTrack StringToInstrumentTrack( const RString& s );
|
||||
|
||||
/** @brief The collection of lyrics for the Song. */
|
||||
struct LyricSegment
|
||||
{
|
||||
float m_fStartTime; /** @brief When does the lyric show up? */
|
||||
RString m_sLyric; /** @brief The lyrics themselves. */
|
||||
RageColor m_Color; /** @brief The color of the lyrics. */
|
||||
};
|
||||
|
||||
/** @brief Holds all music metadata and steps for one song. */
|
||||
class Song
|
||||
{
|
||||
RString m_sSongDir;
|
||||
public:
|
||||
void SetSongDir( const RString sDir ) { m_sSongDir = sDir; }
|
||||
RString GetSongDir() { return m_sSongDir; }
|
||||
|
||||
/** @brief When should this song be displayed in the music wheel? */
|
||||
enum SelectionDisplay
|
||||
{
|
||||
SHOW_ALWAYS, /**< always show on the wheel. */
|
||||
SHOW_NEVER /**< never show on the wheel (unless song hiding is turned off). */
|
||||
} m_SelectionDisplay;
|
||||
|
||||
Song();
|
||||
~Song();
|
||||
void Reset();
|
||||
void DetachSteps();
|
||||
|
||||
/**
|
||||
* @brief Load a song from the chosen directory.
|
||||
*
|
||||
* This assumes that there is no song present right now.
|
||||
* @param sDir the song directory from which to load. */
|
||||
bool LoadFromSongDir( RString sDir );
|
||||
// This one takes the effort to reuse Steps pointers as best as it can
|
||||
bool ReloadFromSongDir( RString sDir );
|
||||
|
||||
/**
|
||||
* @brief Call this after loading a song to clean up invalid data.
|
||||
* @param fromCache was this data loaded from the cache file?
|
||||
* @param duringCache was this data loaded during the cache process? */
|
||||
void TidyUpData( bool fromCache = false, bool duringCache = false );
|
||||
|
||||
/**
|
||||
* @brief Get the new radar values, and determine the last second at the same time.
|
||||
* This is called by TidyUpData, after saving the Song.
|
||||
* @param fromCache was this data loaded from the cache file?
|
||||
* @param duringCache was this data loaded during the cache process? */
|
||||
void ReCalculateRadarValuesAndLastSecond(bool fromCache = false, bool duringCache = false);
|
||||
/**
|
||||
* @brief Translate any titles that aren't in english.
|
||||
* This is called by TidyUpData. */
|
||||
void TranslateTitles();
|
||||
|
||||
/**
|
||||
* @brief Save to the new SSC file format.
|
||||
* @param sPath the path where we're saving the file.
|
||||
* @param bSavingCache a flag to determine if we're saving cache data.
|
||||
*/
|
||||
bool SaveToSSCFile( RString sPath, bool bSavingCache );
|
||||
/** @brief Save to the SSC and SM files no matter what. */
|
||||
void Save();
|
||||
/**
|
||||
* @brief Save the current Song to a JSON file.
|
||||
* @return its success or failure. */
|
||||
bool SaveToJsonFile( RString sPath );
|
||||
/**
|
||||
* @brief Save the current Song to a cache file using the preferred format.
|
||||
* @return its success or failure. */
|
||||
bool SaveToCacheFile();
|
||||
/**
|
||||
* @brief Save the current Song to a SM file.
|
||||
* @return its success or failure. */
|
||||
bool SaveToSMFile();
|
||||
/**
|
||||
* @brief Save the current Song to a DWI file if possible.
|
||||
* @return its success or failure. */
|
||||
bool SaveToDWIFile();
|
||||
|
||||
const RString &GetSongFilePath() const;
|
||||
RString GetCacheFilePath() const;
|
||||
|
||||
void AddAutoGenNotes();
|
||||
/**
|
||||
* @brief Automatically generate steps from one type to another.
|
||||
* @param ntTo the StepsType we're making.
|
||||
* @param ntFrom the StepsType we're generating from.
|
||||
*/
|
||||
void AutoGen( StepsType ntTo, StepsType ntFrom );
|
||||
void RemoveAutoGenNotes();
|
||||
|
||||
// Directory this song data came from:
|
||||
const RString &GetSongDir() const { return m_sSongDir; }
|
||||
|
||||
/**
|
||||
* @brief Filename associated with this file.
|
||||
* This will always have a .SSC extension. If we loaded a .SSC, this will
|
||||
* point to it, but if we loaded any other type, this will point to
|
||||
* a generated .SSC filename. */
|
||||
RString m_sSongFileName;
|
||||
|
||||
/** @brief The group this Song is in. */
|
||||
RString m_sGroupName;
|
||||
|
||||
/**
|
||||
* @brief the Profile this came from.
|
||||
* This is ProfileSlot_Invalid if it wasn't loaded from a profile. */
|
||||
ProfileSlot m_LoadedFromProfile;
|
||||
/** @brief Is the song file itself a symlink to another file? */
|
||||
bool m_bIsSymLink;
|
||||
bool m_bEnabled;
|
||||
|
||||
/** @brief The title of the Song. */
|
||||
RString m_sMainTitle;
|
||||
/** @brief The subtitle of the Song, if it exists. */
|
||||
RString m_sSubTitle;
|
||||
/** @brief The artist of the Song, if it exists. */
|
||||
RString m_sArtist;
|
||||
/** @brief The transliterated title of the Song, if it exists. */
|
||||
RString m_sMainTitleTranslit;
|
||||
/** @brief The transliterated subtitle of the Song, if it exists. */
|
||||
RString m_sSubTitleTranslit;
|
||||
/** @brief The transliterated artist of the Song, if it exists. */
|
||||
RString m_sArtistTranslit;
|
||||
|
||||
/* If PREFSMAN->m_bShowNative is off, these are the same as GetTranslit*
|
||||
* below. Otherwise, they return the main titles. */
|
||||
RString GetDisplayMainTitle() const;
|
||||
RString GetDisplaySubTitle() const;
|
||||
RString GetDisplayArtist() const;
|
||||
|
||||
/**
|
||||
* @brief Retrieve the transliterated title, or the main title if there is no translit.
|
||||
* @return the proper title. */
|
||||
RString GetTranslitMainTitle() const
|
||||
{
|
||||
return m_sMainTitleTranslit.size()? m_sMainTitleTranslit: m_sMainTitle;
|
||||
}
|
||||
/**
|
||||
* @brief Retrieve the transliterated subtitle, or the main subtitle if there is no translit.
|
||||
* @return the proper subtitle. */
|
||||
RString GetTranslitSubTitle() const
|
||||
{
|
||||
return m_sSubTitleTranslit.size()? m_sSubTitleTranslit: m_sSubTitle;
|
||||
}
|
||||
/**
|
||||
* @brief Retrieve the transliterated artist, or the main artist if there is no translit.
|
||||
* @return the proper artist. */
|
||||
RString GetTranslitArtist() const
|
||||
{
|
||||
return m_sArtistTranslit.size()? m_sArtistTranslit:m_sArtist;
|
||||
}
|
||||
|
||||
// "title subtitle"
|
||||
RString GetDisplayFullTitle() const;
|
||||
RString GetTranslitFullTitle() const;
|
||||
|
||||
/** @brief The version of the song/file. */
|
||||
float m_fVersion;
|
||||
/** @brief The genre of the song/file. */
|
||||
RString m_sGenre;
|
||||
|
||||
/**
|
||||
* @brief The person who worked with the song file who should be credited.
|
||||
* This is read and saved, but never actually used. */
|
||||
RString m_sCredit;
|
||||
|
||||
RString m_sOrigin; // song origin (for .ssc format)
|
||||
|
||||
RString m_sMusicFile;
|
||||
RString m_sInstrumentTrackFile[NUM_InstrumentTrack];
|
||||
|
||||
/** @brief The length of the music file. */
|
||||
float m_fMusicLengthSeconds;
|
||||
float m_fMusicSampleStartSeconds;
|
||||
float m_fMusicSampleLengthSeconds;
|
||||
DisplayBPM m_DisplayBPMType;
|
||||
float m_fSpecifiedBPMMin;
|
||||
float m_fSpecifiedBPMMax; // if a range, then Min != Max
|
||||
|
||||
RString m_sBannerFile; // typically a 16:5 ratio graphic (e.g. 256x80)
|
||||
RString m_sJacketFile; // typically square (e.g. 192x192, 256x256)
|
||||
RString m_sCDFile; // square (e.g. 128x128 [DDR 1st-3rd])
|
||||
RString m_sDiscFile; // rectangular (e.g. 256x192 [Pump], 200x150 [MGD3])
|
||||
/** @brief The location of the lyrics file, if it exists. */
|
||||
RString m_sLyricsFile;
|
||||
RString m_sBackgroundFile;
|
||||
RString m_sCDTitleFile;
|
||||
RString m_sPreviewVidFile;
|
||||
|
||||
AttackArray m_Attacks;
|
||||
vector<RString> m_sAttackString;
|
||||
|
||||
RString GetMusicPath() const;
|
||||
RString GetInstrumentTrackPath( InstrumentTrack it ) const;
|
||||
RString GetBannerPath() const;
|
||||
RString GetJacketPath() const;
|
||||
RString GetCDImagePath() const;
|
||||
RString GetDiscPath() const;
|
||||
RString GetLyricsPath() const;
|
||||
RString GetBackgroundPath() const;
|
||||
RString GetCDTitlePath() const;
|
||||
RString GetPreviewVidPath() const;
|
||||
|
||||
// For loading only:
|
||||
bool m_bHasMusic, m_bHasBanner, m_bHasBackground;
|
||||
|
||||
bool HasMusic() const;
|
||||
bool HasInstrumentTrack( InstrumentTrack it ) const;
|
||||
/**
|
||||
* @brief Does this song have a banner?
|
||||
* @return true if it does, false otherwise. */
|
||||
bool HasBanner() const;
|
||||
/**
|
||||
* @brief Does this song have a background image?
|
||||
* @return true if it does, false otherwise. */
|
||||
bool HasBackground() const;
|
||||
bool HasJacket() const;
|
||||
bool HasCDImage() const;
|
||||
bool HasDisc() const;
|
||||
bool HasCDTitle() const;
|
||||
//bool HasMovieBackground() const;
|
||||
bool HasBGChanges() const;
|
||||
bool HasLyrics() const;
|
||||
bool HasAttacks() const;
|
||||
bool HasPreviewVid() const;
|
||||
|
||||
bool Matches(RString sGroup, RString sSong) const;
|
||||
|
||||
/** @brief The Song's TimingData. */
|
||||
TimingData m_SongTiming;
|
||||
|
||||
float GetFirstBeat() const;
|
||||
float GetFirstSecond() const;
|
||||
float GetLastBeat() const;
|
||||
float GetLastSecond() const;
|
||||
float GetSpecifiedLastBeat() const;
|
||||
float GetSpecifiedLastSecond() const;
|
||||
|
||||
void SetFirstSecond(const float f);
|
||||
void SetLastSecond(const float f);
|
||||
void SetSpecifiedLastSecond(const float f);
|
||||
|
||||
typedef vector<BackgroundChange> VBackgroundChange;
|
||||
private:
|
||||
/** @brief The first second that a note is hit. */
|
||||
float firstSecond;
|
||||
/** @brief The last second that a note is hit. */
|
||||
float lastSecond;
|
||||
/** @brief The last second of the song for playing purposes. */
|
||||
float specifiedLastSecond;
|
||||
/**
|
||||
* @brief The background changes (sorted by layer) that are for this Song.
|
||||
* This uses an AutoPtr instead of a raw pointer so that the
|
||||
* auto gen'd copy constructor works correctly.
|
||||
* This must be sorted before gameplay. */
|
||||
AutoPtrCopyOnWrite<VBackgroundChange> m_BackgroundChanges[NUM_BackgroundLayer];
|
||||
/**
|
||||
* @brief The foreground changes that are for this Song.
|
||||
* This uses an AutoPtr instead of a raw pointer so that the
|
||||
* auto gen'd copy constructor works correctly.
|
||||
* This must be sorted before gameplay. */
|
||||
AutoPtrCopyOnWrite<VBackgroundChange> m_ForegroundChanges;
|
||||
|
||||
vector<RString> GetChangesToVectorString(const vector<BackgroundChange> & changes) const;
|
||||
public:
|
||||
const vector<BackgroundChange> &GetBackgroundChanges( BackgroundLayer bl ) const;
|
||||
vector<BackgroundChange> &GetBackgroundChanges( BackgroundLayer bl );
|
||||
const vector<BackgroundChange> &GetForegroundChanges() const;
|
||||
vector<BackgroundChange> &GetForegroundChanges();
|
||||
|
||||
vector<RString> GetBGChanges1ToVectorString() const;
|
||||
vector<RString> GetBGChanges2ToVectorString() const;
|
||||
vector<RString> GetFGChanges1ToVectorString() const;
|
||||
|
||||
vector<RString> GetInstrumentTracksToVectorString() const;
|
||||
|
||||
/**
|
||||
* @brief The list of LyricSegments.
|
||||
* This must be sorted before gameplay. */
|
||||
vector<LyricSegment> m_LyricSegments;
|
||||
|
||||
/* [splittiming]
|
||||
void AddBPMSegment( const BPMSegment &seg ) { m_Timing.AddBPMSegment( seg ); }
|
||||
void AddStopSegment( const StopSegment &seg ) { m_Timing.AddStopSegment( seg ); }
|
||||
void AddWarpSegment( const WarpSegment &seg ) { m_Timing.AddWarpSegment( seg ); }
|
||||
*/
|
||||
void AddBackgroundChange( BackgroundLayer blLayer, BackgroundChange seg );
|
||||
void AddForegroundChange( BackgroundChange seg );
|
||||
void AddLyricSegment( LyricSegment seg );
|
||||
|
||||
void GetDisplayBpms( DisplayBpms &AddTo ) const;
|
||||
const BackgroundChange &GetBackgroundAtBeat( BackgroundLayer iLayer, float fBeat ) const;
|
||||
|
||||
/* [splittiming]
|
||||
float GetBPMAtBeat( float fBeat ) const { return m_Timing.GetBPMAtBeat( fBeat ); }
|
||||
void SetBPMAtBeat( float fBeat, float fBPM ) { m_Timing.SetBPMAtBeat( fBeat, fBPM ); }
|
||||
BPMSegment& GetBPMSegmentAtBeat( float fBeat ) { return m_Timing.GetBPMSegmentAtBeat( fBeat ); }
|
||||
*/
|
||||
|
||||
Steps *CreateSteps();
|
||||
void InitSteps(Steps *pSteps);
|
||||
|
||||
/* [splittiming]
|
||||
float SongGetBeatFromElapsedTime( float fElapsedTime ) const
|
||||
{
|
||||
return m_SongTiming.GetBeatFromElapsedTime( fElapsedTime );
|
||||
}
|
||||
float StepsGetBeatFromElapsedTime( float fElapsedTime, const Steps &steps ) const
|
||||
{
|
||||
return steps.m_Timing.GetBeatFromElapsedTime( fElapsedTime );
|
||||
}
|
||||
|
||||
float SongGetElapsedTimeFromBeat( float fBeat ) const
|
||||
{
|
||||
return m_SongTiming.GetElapsedTimeFromBeat( fBeat );
|
||||
}
|
||||
float StepsGetElapsedTimeFromBeat( float fBeat, const Steps &steps ) const
|
||||
{
|
||||
return steps.m_Timing.GetElapsedTimeFromBeat( fBeat );
|
||||
}
|
||||
*/
|
||||
|
||||
/* [splittiming]
|
||||
float GetBeatFromElapsedTime( float fElapsedTime ) const
|
||||
{
|
||||
return m_Timing.GetBeatFromElapsedTime( fElapsedTime );
|
||||
}
|
||||
float GetElapsedTimeFromBeat( float fBeat ) const { return m_Timing.GetElapsedTimeFromBeat( fBeat ); }
|
||||
*/
|
||||
|
||||
bool HasSignificantBpmChangesOrStops() const;
|
||||
float GetStepsSeconds() const;
|
||||
bool IsLong() const;
|
||||
bool IsMarathon() const;
|
||||
|
||||
bool SongCompleteForStyle( const Style *st ) const;
|
||||
bool HasStepsType( StepsType st ) const;
|
||||
bool HasStepsTypeAndDifficulty( StepsType st, Difficulty dc ) const;
|
||||
const vector<Steps*>& GetAllSteps() const { return m_vpSteps; }
|
||||
const vector<Steps*>& GetStepsByStepsType( StepsType st ) const { return m_vpStepsByType[st]; }
|
||||
bool IsEasy( StepsType st ) const;
|
||||
bool IsTutorial() const;
|
||||
bool HasEdits( StepsType st ) const;
|
||||
|
||||
void SetEnabled( bool b ) { m_bEnabled = b; }
|
||||
bool GetEnabled() const { return m_bEnabled; }
|
||||
/**
|
||||
* @brief Determine if the song should be shown on the MusicWheel normally.
|
||||
* Songs that are not displayed normally may still be available during
|
||||
* random selection, extra stages, or other special conditions.
|
||||
* @return true if displayed normally, false otherwise. */
|
||||
bool NormallyDisplayed() const;
|
||||
bool ShowInDemonstrationAndRanking() const;
|
||||
|
||||
/**
|
||||
* @brief Add the chosen Steps to the Song.
|
||||
* We are responsible for deleting the memory pointed to by pSteps!
|
||||
* @param pSteps the new steps. */
|
||||
void AddSteps( Steps* pSteps );
|
||||
void DeleteSteps( const Steps* pSteps, bool bReAutoGen = true );
|
||||
|
||||
void FreeAllLoadedFromProfile( ProfileSlot slot = ProfileSlot_Invalid, const set<Steps*> *setInUse = NULL );
|
||||
bool WasLoadedFromProfile() const { return m_LoadedFromProfile != ProfileSlot_Invalid; }
|
||||
void GetStepsLoadedFromProfile( ProfileSlot slot, vector<Steps*> &vpStepsOut ) const;
|
||||
int GetNumStepsLoadedFromProfile( ProfileSlot slot ) const;
|
||||
bool IsEditAlreadyLoaded( Steps* pSteps ) const;
|
||||
|
||||
bool IsStepsUsingDifferentTiming(Steps *pSteps ) const;
|
||||
|
||||
/**
|
||||
* @brief An array of keysound file names (e.g. "beep.wav").
|
||||
* The index in this array corresponds to the index in TapNote.
|
||||
* If you change the index in here, you must change all NoteData too.
|
||||
* Any note that doesn't have a value in the range of this array
|
||||
* means "this note doesn't have a keysound". */
|
||||
vector<RString> m_vsKeysoundFile;
|
||||
|
||||
CachedObject<Song> m_CachedObject;
|
||||
|
||||
RString GetAttackString() const
|
||||
{
|
||||
return join(":", this->m_sAttackString);
|
||||
}
|
||||
|
||||
// Lua
|
||||
void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
/** @brief the Steps that belong to this Song. */
|
||||
vector<Steps*> m_vpSteps;
|
||||
/** @brief the Steps of a particular StepsType that belong to this Song. */
|
||||
vector<Steps*> m_vpStepsByType[NUM_StepsType];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @author Chris Danford, Glenn Maynard (c) 2001-2004
|
||||
* @section LICENSE
|
||||
* 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.
|
||||
*/
|
||||
|
||||
+2130
-2112
File diff suppressed because it is too large
Load Diff
@@ -810,6 +810,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\
|
||||
<File
|
||||
RelativePath="CourseWriterCRS.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CreateZip.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CreateZip.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="DateTime.cpp">
|
||||
</File>
|
||||
|
||||
@@ -1074,6 +1074,14 @@
|
||||
RelativePath="CourseWriterCRS.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CreateZip.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CreateZip.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="DateTime.cpp"
|
||||
>
|
||||
|
||||
@@ -1172,6 +1172,14 @@
|
||||
RelativePath="ControllerStateDisplay.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CreateZip.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CreateZip.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="CryptHelpers.cpp"
|
||||
>
|
||||
|
||||
@@ -455,6 +455,7 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)</Command>
|
||||
<ClCompile Include="Command.cpp" />
|
||||
<ClCompile Include="CommonMetrics.cpp" />
|
||||
<ClCompile Include="ControllerStateDisplay.cpp" />
|
||||
<ClCompile Include="CreateZip.cpp" />
|
||||
<ClCompile Include="CryptHelpers.cpp" />
|
||||
<ClCompile Include="DateTime.cpp" />
|
||||
<ClCompile Include="Difficulty.cpp" />
|
||||
@@ -1767,6 +1768,7 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)</Command>
|
||||
<ClInclude Include="Command.h" />
|
||||
<ClInclude Include="CommonMetrics.h" />
|
||||
<ClInclude Include="ControllerStateDisplay.h" />
|
||||
<ClInclude Include="CreateZip.h" />
|
||||
<ClInclude Include="CryptHelpers.h" />
|
||||
<ClInclude Include="DateTime.h" />
|
||||
<ClInclude Include="Difficulty.h" />
|
||||
|
||||
@@ -375,6 +375,9 @@
|
||||
<ClCompile Include="ControllerStateDisplay.cpp">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CreateZip.cpp">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CryptHelpers.cpp">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClCompile>
|
||||
@@ -1871,6 +1874,9 @@
|
||||
<ClInclude Include="ControllerStateDisplay.h">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CreateZip.h">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CryptHelpers.h">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -467,6 +467,7 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)</Command>
|
||||
<ClCompile Include="Command.cpp" />
|
||||
<ClCompile Include="CommonMetrics.cpp" />
|
||||
<ClCompile Include="ControllerStateDisplay.cpp" />
|
||||
<ClCompile Include="CreateZip.cpp" />
|
||||
<ClCompile Include="CryptHelpers.cpp" />
|
||||
<ClCompile Include="DateTime.cpp" />
|
||||
<ClCompile Include="Difficulty.cpp" />
|
||||
@@ -1779,6 +1780,7 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)</Command>
|
||||
<ClInclude Include="Command.h" />
|
||||
<ClInclude Include="CommonMetrics.h" />
|
||||
<ClInclude Include="ControllerStateDisplay.h" />
|
||||
<ClInclude Include="CreateZip.h" />
|
||||
<ClInclude Include="CryptHelpers.h" />
|
||||
<ClInclude Include="DateTime.h" />
|
||||
<ClInclude Include="Difficulty.h" />
|
||||
|
||||
@@ -375,6 +375,9 @@
|
||||
<ClCompile Include="ControllerStateDisplay.cpp">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CreateZip.cpp">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CryptHelpers.cpp">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClCompile>
|
||||
@@ -1871,6 +1874,9 @@
|
||||
<ClInclude Include="ControllerStateDisplay.h">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CreateZip.h">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CryptHelpers.h">
|
||||
<Filter>Data Structures</Filter>
|
||||
</ClInclude>
|
||||
|
||||
Reference in New Issue
Block a user