<ActorFrame><children>

    <Layer
        Type= "Quad"
        InitCommand= "hidden,1;sleep,9999"
    />

    <Layer
        Type= "Quad"
        OnCommand="%function(self)

            ------------------------
            -- Const
            ------------------------

            UPDATE = 'Update';
            -- HS_BASE = 3.0;
            BASE_BPM = 200;

            ------------------------
            -- Function
            ------------------------
            --[[
                Rateオプションの値を取得
            ]]
            function getRateMod()
                local so = SCREENMAN:GetTopScreen():GetChild('SongOptions')
                local s = '';
                if not so then
                    return 1.0;
                else
                    s = so:GetText();
                end

                if not s then
                    return 1.0;
                end;

                local fbegin = string.find(s,'.',1,true);
                local fend = string.find(s,'xMusic');
                if fbegin and fend then
                    return tonumber(string.sub(s,fbegin-1,fend-1));
                else
                    return 1.0;
                end
            end

            --[[
                プレイヤーの使用しているHiSpeedオプションを取得
                @args プレイヤー1Pまたは2P (0,1)
            ]]
            function getPlayerHiSpeed(player)
                local hispeed = 1.0;
                for i = 1, 160 do
                    if (GAMESTATE:PlayerIsUsingModifier(player, tostring(i*0.05)..'x')) then
                        hispeed = i*0.05;
                    end
                end
                return hispeed;
            end

            --[[
                ノートの位置拍数を求める
                @args (小節,小節内の拍数,端数 1以下の値)
            ]]
            function calcBeat(measure, beat, fraction)
                return (measure-1) * 4.0 + beat + fraction;
            end

            --[[
                指定した拍数にかかる時間を求める
                @args (拍数, BPM)
            ]]
            function calcTime(beatLength, bpm)
                return beatLength * (60.0/bpm);
            end

            function getSpeedTime(beatLength)
                return 1.0/calcTime(beatLength, BASE_BPM);
            end

            function getTimeString(beatLength, bpm)
                return '*' .. tostring(1.0/calcTime(beatLength, bpm));
            end

            function getTimeString(beatLength)
                return '*' .. tostring(1.0/calcTime(beatLength, BASE_BPM));
            end

            --[[
                スピード変更Mod
                @args (変更速度, 値)
            ]]
            function ApplyXMod(velocity, value)
                GAMESTATE:ApplyGameCommand('mod, *'..tostring(velocity*hfvP1)..' '..tostring(hispeedP1*value)..'x', 1);
                GAMESTATE:ApplyGameCommand('mod, *'..tostring(velocity*hfvP2)..' '..tostring(hispeedP2*value)..'x', 2);
            end

            --[[
                フレーム待機
            ]]
            function WaitFrame()
				self:sleep(0.02);
            end

            --[[
                Modsを更新
                @args (Beat位置)
            ]]
            function UpdateMods(beat)

                -- Modループ
                for m, mod in ipairs(mods) do
                    if (beat >= mod[1] and lastBeat < mod[1]) then
                        GAMESTATE:ApplyGameCommand('mod, '..mod[2]);
                    elseif (beat < mod[1]) then
                        break
                    end
                end

                -- SpeedModループ
                for e, event in ipairs(speedMods) do
                    if (beat >= event[1] and lastBeat < event[1]) then
                        if (event[2] == 'A0') then
                            ApplyXMod(getSpeedTime(2.6), 0.25);
                        end
                        if (event[2] == 'A1') then
                            ApplyXMod(getSpeedTime(4), 1.0);
                        end
                    elseif (beat < event[1]) then
                        break
                    end
                end

                lastBeat = beat;

            end

            -----------------------
            -- Mod Event
            -----------------------
            -- Gimmik Mod
            mods = {
                {calcBeat(6, 2, 4/5), '*100000 50.0% stealth'},
                {calcBeat(6, 2, 4/5), '*100000 31.25% flip'},
                {calcBeat(6, 2, 4/5), '*100000 -18.75% invert'},
                {calcBeat(6, 2, 4/5), '*100000 -18.75% split'},
                {calcBeat(6, 2, 4/5), '*100000 18.75% alternate'},
                {calcBeat(6, 2, 4/5), '*100000 50% reverse'},
                {calcBeat(7, 2, 2/5), getTimeString(4) .. ' 0% flip'},
                {calcBeat(7, 2, 2/5), getTimeString(4) .. ' 0% invert'},
                {calcBeat(7, 2, 2/5), getTimeString(4) .. ' 0% split'},
                {calcBeat(7, 2, 2/5), getTimeString(4) .. ' 0% alternate'},
                {calcBeat(7, 2, 2/5), getTimeString(4) .. ' 0% reverse'},
                {calcBeat(7, 2, 2/5), getTimeString(8) .. ' no stealth'},
                {calcBeat(281, 0, 0), getTimeString(4) .. ' 50.0% stealth'},
                {calcBeat(281, 0, 0), getTimeString(0.5) .. ' 90% reverse'},
                {calcBeat(281, 0, 1/2), getTimeString(0.5) .. ' 10% reverse'},
                {calcBeat(281, 1, 0), getTimeString(0.5) .. ' 80% reverse'},
                {calcBeat(281, 1, 1/2), getTimeString(0.5) .. ' 20% reverse'},
                {calcBeat(281, 2, 0), getTimeString(0.5) .. ' 70% reverse'},
                {calcBeat(281, 2, 1/2), getTimeString(0.5) .. ' 30% reverse'},
                {calcBeat(281, 3, 0), getTimeString(0.5) .. ' 60% reverse'},
                {calcBeat(281, 3, 1/2), getTimeString(0.5) .. ' 40% reverse'},
                {calcBeat(282, 0, 0), getTimeString(0.5) .. ' 50% reverse'},
                {calcBeat(282, 0, 0), getTimeString(0.5) .. ' 50.0% stealth'},
                {calcBeat(282, 0, 0), getTimeString(0.5) .. ' 31.25% flip'},
                {calcBeat(282, 0, 0), getTimeString(0.5) .. ' -18.75% invert'},
                {calcBeat(282, 0, 0), getTimeString(0.5) .. ' -18.75% split'},
                {calcBeat(282, 0, 0), getTimeString(0.5) .. ' 18.75% alternate'},
                {calcBeat(282, 0, 0), getTimeString(8) .. ' 100% dark'}
            }

            -- SpeedMod
            speedMods = {
                {calcBeat(207, 0, 0),      	'A0' },
                {calcBeat(207, 2, 1/2),     'A1' },
            }

            -----------------------
            -- Cache
            -----------------------
            lastBeat = -16.0;
            hispeedP1 = getPlayerHiSpeed(0);
            hispeedP2 = getPlayerHiSpeed(1);

            hfvP1 = hispeedP1 / getRateMod();
            hfvP2 = hispeedP2 / getRateMod();
            -----------------------

            self:sleep(1);
            self:queuecommand( UPDATE );
        end"

        UpdateCommand="%function(self)
            beat = GAMESTATE:GetSongBeat();
            UpdateMods(beat);
            WaitFrame();
            self:queuecommand( UPDATE );
        end"
    />

</children></ActorFrame>