1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-18 19:32:58 +08:00
osu-lazer/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

147 lines
4.9 KiB
C#
Raw Normal View History

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2018-04-13 17:19:50 +08:00
2022-06-17 15:37:17 +08:00
#nullable disable
using System;
using System.Collections.Generic;
using osu.Game.Beatmaps;
2018-11-28 16:20:37 +08:00
using osu.Game.Replays.Legacy;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Replays.Types;
2018-04-13 17:19:50 +08:00
namespace osu.Game.Rulesets.Mania.Replays
{
public class ManiaReplayFrame : ReplayFrame, IConvertibleReplayFrame
{
public List<ManiaAction> Actions = new List<ManiaAction>();
2018-04-13 17:19:50 +08:00
public ManiaReplayFrame()
{
}
2018-04-13 17:19:50 +08:00
public ManiaReplayFrame(double time, params ManiaAction[] actions)
: base(time)
{
Actions.AddRange(actions);
}
2018-04-13 17:19:50 +08:00
2020-03-25 19:21:34 +08:00
public void FromLegacy(LegacyReplayFrame legacyFrame, IBeatmap beatmap, ReplayFrame lastFrame = null)
{
var maniaBeatmap = (ManiaBeatmap)beatmap;
2018-04-13 17:19:50 +08:00
var normalAction = ManiaAction.Key1;
var specialAction = ManiaAction.Special1;
2018-04-13 17:19:50 +08:00
int activeColumns = (int)(legacyFrame.MouseX ?? 0);
int counter = 0;
2019-04-01 11:16:05 +08:00
while (activeColumns > 0)
{
bool isSpecial = isColumnAtIndexSpecial(maniaBeatmap, counter);
2018-04-13 17:19:50 +08:00
if ((activeColumns & 1) > 0)
Actions.Add(isSpecial ? specialAction : normalAction);
2018-04-13 17:19:50 +08:00
if (isSpecial)
specialAction++;
else
normalAction++;
2018-04-13 17:19:50 +08:00
counter++;
activeColumns >>= 1;
}
}
2020-03-24 13:13:46 +08:00
2020-03-25 19:21:34 +08:00
public LegacyReplayFrame ToLegacy(IBeatmap beatmap)
2020-03-24 13:13:46 +08:00
{
var maniaBeatmap = (ManiaBeatmap)beatmap;
2020-03-24 13:13:46 +08:00
int keys = 0;
2020-03-24 13:13:46 +08:00
foreach (var action in Actions)
{
switch (action)
{
case ManiaAction.Special1:
keys |= 1 << getSpecialColumnIndex(maniaBeatmap, 0);
2020-03-24 13:13:46 +08:00
break;
case ManiaAction.Special2:
keys |= 1 << getSpecialColumnIndex(maniaBeatmap, 1);
2020-03-24 13:13:46 +08:00
break;
default:
// the index in lazer, which doesn't include special keys.
int nonSpecialKeyIndex = action - ManiaAction.Key1;
// the index inclusive of special keys.
int overallIndex = 0;
// iterate to find the index including special keys.
for (; overallIndex < maniaBeatmap.TotalColumns; overallIndex++)
{
// skip over special columns.
if (isColumnAtIndexSpecial(maniaBeatmap, overallIndex))
continue;
// found a non-special column to use.
if (nonSpecialKeyIndex == 0)
break;
// found a non-special column but not ours.
nonSpecialKeyIndex--;
}
keys |= 1 << overallIndex;
2020-03-24 13:13:46 +08:00
break;
}
}
return new LegacyReplayFrame(Time, keys, null, ReplayButtonState.None);
}
/// <summary>
/// Find the overall index (across all stages) for a specified special key.
/// </summary>
/// <param name="maniaBeatmap">The beatmap.</param>
/// <param name="specialOffset">The special key offset (0 is S1).</param>
/// <returns>The overall index for the special column.</returns>
private int getSpecialColumnIndex(ManiaBeatmap maniaBeatmap, int specialOffset)
{
for (int i = 0; i < maniaBeatmap.TotalColumns; i++)
{
if (isColumnAtIndexSpecial(maniaBeatmap, i))
{
if (specialOffset == 0)
return i;
specialOffset--;
}
}
2020-04-15 12:08:15 +08:00
throw new ArgumentException("Special key index is too high.", nameof(specialOffset));
}
/// <summary>
/// Check whether the column at an overall index (across all stages) is a special column.
/// </summary>
/// <param name="beatmap">The beatmap.</param>
/// <param name="index">The overall index to check.</param>
private bool isColumnAtIndexSpecial(ManiaBeatmap beatmap, int index)
{
foreach (var stage in beatmap.Stages)
{
if (index >= stage.Columns)
{
index -= stage.Columns;
continue;
}
return stage.IsSpecialColumn(index);
}
throw new ArgumentException("Column index is too high.", nameof(index));
}
}
}