diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs
index 70270af6c9..dc80cea562 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs
@@ -35,9 +35,9 @@ namespace osu.Game.Rulesets.Mania.Mods
}
// Like with hit objects, we need to generate one speed adjustment per bar line
- foreach (DrawableBarLine barLine in rulesetContainer.BarLines)
+ foreach (BarLine barLine in rulesetContainer.BarLines)
{
- var controlPoint = rulesetContainer.CreateControlPointAt(barLine.HitObject.StartTime);
+ var controlPoint = rulesetContainer.CreateControlPointAt(barLine.StartTime);
// Beat length has too large of an effect for gravity, so we'll force it to a constant value for now
controlPoint.TimingPoint.BeatLength = 1000;
@@ -45,4 +45,4 @@ namespace osu.Game.Rulesets.Mania.Mods
}
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs
index 1932038411..88727df405 100644
--- a/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs
+++ b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs
@@ -83,11 +83,11 @@ namespace osu.Game.Rulesets.Mania.Tests
Add(inputManager);
ManiaPlayfield playfield;
- inputManager.Add(playfield = new ManiaPlayfield(cols)
+ inputManager.Add(playfield = new ManiaPlayfield(cols, false)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- SpecialColumnPosition = specialPos
+ //SpecialColumnPosition = specialPos
});
playfield.Inverted.Value = inverted;
@@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Mania.Tests
Add(inputManager);
ManiaPlayfield playfield;
- inputManager.Add(playfield = new ManiaPlayfield(4)
+ inputManager.Add(playfield = new ManiaPlayfield(4,false)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs
index 2d553f8639..6140452bb3 100644
--- a/osu.Game.Rulesets.Mania/UI/Column.cs
+++ b/osu.Game.Rulesets.Mania/UI/Column.cs
@@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mania.UI
{
Name = "Hit target + hit objects",
RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Top = ManiaPlayfield.HIT_TARGET_POSITION },
+ Padding = new MarginPadding { Top = ManiaColumnGroup.HIT_TARGET_POSITION },
Children = new Drawable[]
{
new Container
@@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Mania.UI
{
Name = "Key",
RelativeSizeAxes = Axes.X,
- Height = ManiaPlayfield.HIT_TARGET_POSITION,
+ Height = ManiaColumnGroup.HIT_TARGET_POSITION,
Children = new Drawable[]
{
new Box
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaColumnGroup.cs b/osu.Game.Rulesets.Mania/UI/ManiaColumnGroup.cs
new file mode 100644
index 0000000000..a37fa913bc
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/UI/ManiaColumnGroup.cs
@@ -0,0 +1,213 @@
+using System;
+using System.Collections.Generic;
+using OpenTK;
+using OpenTK.Graphics;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using osu.Game.Graphics;
+using osu.Framework.Allocation;
+using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.UI;
+using osu.Game.Rulesets.Timing;
+
+namespace osu.Game.Rulesets.Mania.UI
+{
+ ///
+ /// controls that from up to down
+ ///
+ internal class ManiaColumnGroup : ScrollingPlayfield
+ {
+ public const float HIT_TARGET_POSITION = 50;
+
+ private SpecialColumnPosition specialColumnPosition;
+
+ ///
+ /// The style to use for the special column.
+ ///
+ public SpecialColumnPosition SpecialColumnPosition
+ {
+ get { return specialColumnPosition; }
+ set
+ {
+ if (IsLoaded)
+ throw new InvalidOperationException($"Setting {nameof(SpecialColumnPosition)} after the playfield is loaded requires re-creating the playfield.");
+ specialColumnPosition = value;
+ }
+ }
+
+ private readonly FillFlowContainer columns;
+ public IEnumerable Columns => columns.Children;
+
+ protected override Container Content => content;
+ private readonly Container content;
+
+ private readonly Container judgements;
+ public Container Judgements => judgements;
+
+ private readonly Container topLevelContainer;
+ public Container TopLevelContainer => topLevelContainer;
+
+ private List normalColumnColours = new List();
+ private Color4 specialColumnColour;
+
+ public int ColumnCount { get; protected set; }
+
+ public ManiaColumnGroup(int columnCount) : base(Axes.Y)
+ {
+ ColumnCount = columnCount;
+ Name = "Playfield elements";
+ Anchor = Anchor.TopCentre;
+ Origin = Anchor.TopCentre;
+ //RelativeSizeAxes = Axes.Y;
+ //AutoSizeAxes = Axes.X;
+ InternalChildren = new Drawable[]
+ {
+ new Container
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.Y,
+ AutoSizeAxes = Axes.X,
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ Name = "Columns mask",
+ RelativeSizeAxes = Axes.Y,
+ AutoSizeAxes = Axes.X,
+ Masking = true,
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ Name = "Background",
+ RelativeSizeAxes = Axes.Both,
+ Colour = new Color4(0,0,0,0.8f)
+ },
+ columns = new FillFlowContainer
+ {
+ Name = "Columns",
+ RelativeSizeAxes = Axes.Y,
+ AutoSizeAxes = Axes.X,
+ Direction = FillDirection.Horizontal,
+ Padding = new MarginPadding { Left = 1, Right = 1 },
+ Spacing = new Vector2(1, 0)
+ },
+ }
+ },
+ new Container
+ {
+ Name = "Barlines mask",
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.Y,
+ Width = 1366, // Bar lines should only be masked on the vertical axis
+ BypassAutoSizeAxes = Axes.Both,
+ Masking = true,
+ Child = content = new Container
+ {
+ Name = "Bar lines",
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.Y,
+ Padding = new MarginPadding { Top = HIT_TARGET_POSITION }
+ }
+ },
+ judgements = new Container
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Both,
+ Y = HIT_TARGET_POSITION + 150,
+ BypassAutoSizeAxes = Axes.Both
+ },
+ topLevelContainer = new Container { RelativeSizeAxes = Axes.Both }
+ }
+ }
+
+ };
+ }
+
+ ///
+ /// Whether the column index is a special column for this playfield.
+ ///
+ /// The 0-based column index.
+ /// Whether the column is a special column.
+ private bool isSpecialColumn(int column)
+ {
+ switch (SpecialColumnPosition)
+ {
+ default:
+ case SpecialColumnPosition.Normal:
+ return ColumnCount % 2 == 1 && column == ColumnCount / 2;
+ case SpecialColumnPosition.Left:
+ return column == 0;
+ case SpecialColumnPosition.Right:
+ return column == ColumnCount - 1;
+ }
+ }
+
+ public void AddColumn(Column c)
+ {
+ c.VisibleTimeRange.BindTo(VisibleTimeRange);
+ topLevelContainer.Add(c.TopLevelContainer.CreateProxy());
+ columns.Add(c);
+ }
+
+ public void AddJudgement(Judgement judgement)
+ {
+ judgements.Clear();
+ judgements.Add(new DrawableManiaJudgement(judgement)
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ });
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ normalColumnColours = new List
+ {
+ colours.RedDark,
+ colours.GreenDark
+ };
+
+ specialColumnColour = colours.BlueDark;
+
+ // Set the special column + colour + key
+ foreach (var column in Columns)
+ {
+ if (!column.IsSpecial)
+ continue;
+
+ column.AccentColour = specialColumnColour;
+ }
+
+ var nonSpecialColumns = Columns.Where(c => !c.IsSpecial).ToList();
+
+ // We'll set the colours of the non-special columns in a separate loop, because the non-special
+ // column colours are mirrored across their centre and special styles mess with this
+ for (int i = 0; i < Math.Ceiling(nonSpecialColumns.Count / 2f); i++)
+ {
+ Color4 colour = normalColumnColours[i % normalColumnColours.Count];
+ nonSpecialColumns[i].AccentColour = colour;
+ nonSpecialColumns[nonSpecialColumns.Count - 1 - i].AccentColour = colour;
+ }
+ }
+
+
+ protected override void Update()
+ {
+ // Due to masking differences, it is not possible to get the width of the columns container automatically
+ // While masking on effectively only the Y-axis, so we need to set the width of the bar line container manually
+ content.Width = columns.Width;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
index 6c164a34f0..ffa74b6ba9 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
@@ -17,48 +17,43 @@ using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Judgements;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Beatmaps.ControlPoints;
+using osu.Framework.MathUtils;
+using osu.Framework.Extensions.IEnumerableExtensions;
namespace osu.Game.Rulesets.Mania.UI
{
public class ManiaPlayfield : ScrollingPlayfield
{
- public const float HIT_TARGET_POSITION = 50;
- private SpecialColumnPosition specialColumnPosition;
///
- /// The style to use for the special column.
+ /// list mania column group
///
- public SpecialColumnPosition SpecialColumnPosition
- {
- get { return specialColumnPosition; }
- set
- {
- if (IsLoaded)
- throw new InvalidOperationException($"Setting {nameof(SpecialColumnPosition)} after the playfield is loaded requires re-creating the playfield.");
- specialColumnPosition = value;
- }
- }
+ FillFlowContainer ListColumnGroup = new FillFlowContainer();
///
/// Whether this playfield should be inverted. This flips everything inside the playfield.
///
public readonly Bindable Inverted = new Bindable(true);
- private readonly FlowContainer columns;
- public IEnumerable Columns => columns.Children;
-
- protected override Container Content => content;
- private readonly Container content;
-
- private List normalColumnColours = new List();
- private Color4 specialColumnColour;
-
- private readonly Container judgements;
+ public List Columns
+ {
+ get
+ {
+ var list = new List();
+ foreach (var single in ListColumnGroup)
+ {
+ list.AddRange(single.Columns);
+ }
+ return list;
+ }
+ }
private readonly int columnCount;
- public ManiaPlayfield(int columnCount)
- : base(Axes.Y)
+ public ManiaPlayfield(int columnCount,bool coop): base(Axes.Y)
{
this.columnCount = columnCount;
@@ -67,172 +62,103 @@ namespace osu.Game.Rulesets.Mania.UI
Inverted.Value = true;
- Container topLevelContainer;
InternalChildren = new Drawable[]
{
- new Container
+ ListColumnGroup=new FillFlowContainer()
{
- Name = "Playfield elements",
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
+ Direction= FillDirection.Horizontal,
RelativeSizeAxes = Axes.Y,
- AutoSizeAxes = Axes.X,
- Children = new Drawable[]
- {
- new Container
- {
- Name = "Columns mask",
- RelativeSizeAxes = Axes.Y,
- AutoSizeAxes = Axes.X,
- Masking = true,
- Children = new Drawable[]
- {
- new Box
- {
- Name = "Background",
- RelativeSizeAxes = Axes.Both,
- Colour = Color4.Black
- },
- columns = new FillFlowContainer
- {
- Name = "Columns",
- RelativeSizeAxes = Axes.Y,
- AutoSizeAxes = Axes.X,
- Direction = FillDirection.Horizontal,
- Padding = new MarginPadding { Left = 1, Right = 1 },
- Spacing = new Vector2(1, 0)
- },
- }
- },
- new Container
- {
- Name = "Barlines mask",
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
- RelativeSizeAxes = Axes.Y,
- Width = 1366, // Bar lines should only be masked on the vertical axis
- BypassAutoSizeAxes = Axes.Both,
- Masking = true,
- Child = content = new Container
- {
- Name = "Bar lines",
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
- RelativeSizeAxes = Axes.Y,
- Padding = new MarginPadding { Top = HIT_TARGET_POSITION }
- }
- },
- judgements = new Container
- {
- Anchor = Anchor.TopCentre,
- Origin = Anchor.Centre,
- AutoSizeAxes = Axes.Both,
- Y = HIT_TARGET_POSITION + 150,
- BypassAutoSizeAxes = Axes.Both
- },
- topLevelContainer = new Container { RelativeSizeAxes = Axes.Both }
- }
+ Anchor= Anchor.Centre,
+ Origin= Anchor.Centre,
+ Spacing=new Vector2(400),
}
};
+ int numberOfGroup = 1;
+ if (coop)
+ numberOfGroup = 2;
+
+ for (int i = 0; i < numberOfGroup; i ++)
+ {
+ var group = new ManiaColumnGroup(columnCount / numberOfGroup)
+ {
+
+ };
+ ListColumnGroup.Add(group);
+ }
+
+
+ foreach (var single in ListColumnGroup)
+ {
+ single.VisibleTimeRange.BindTo(this.VisibleTimeRange);
+ AddNested(single);
+ }
+
var currentAction = ManiaAction.Key1;
for (int i = 0; i < columnCount; i++)
{
var c = new Column();
- c.VisibleTimeRange.BindTo(VisibleTimeRange);
+ //c.Action = c.IsSpecial ? ManiaAction.Special : currentAction++;
+ c.Action = currentAction++;
+ /*
c.IsSpecial = isSpecialColumn(i);
- c.Action = c.IsSpecial ? ManiaAction.Special : currentAction++;
-
topLevelContainer.Add(c.TopLevelContainer.CreateProxy());
-
columns.Add(c);
+ */
+ getFallDownControlContainerByActualColumn(i).AddColumn(c);
AddNested(c);
}
Inverted.ValueChanged += invertedChanged;
Inverted.TriggerChange();
+
}
private void invertedChanged(bool newValue)
{
Scale = new Vector2(1, newValue ? -1 : 1);
- judgements.Scale = Scale;
- }
- [BackgroundDependencyLoader]
- private void load(OsuColour colours)
- {
- normalColumnColours = new List
+ //judgements.Scale = Scale;
+ foreach (var single in ListColumnGroup)
{
- colours.RedDark,
- colours.GreenDark
- };
-
- specialColumnColour = colours.BlueDark;
-
- // Set the special column + colour + key
- foreach (var column in Columns)
- {
- if (!column.IsSpecial)
- continue;
-
- column.AccentColour = specialColumnColour;
- }
-
- var nonSpecialColumns = Columns.Where(c => !c.IsSpecial).ToList();
-
- // We'll set the colours of the non-special columns in a separate loop, because the non-special
- // column colours are mirrored across their centre and special styles mess with this
- for (int i = 0; i < Math.Ceiling(nonSpecialColumns.Count / 2f); i++)
- {
- Color4 colour = normalColumnColours[i % normalColumnColours.Count];
- nonSpecialColumns[i].AccentColour = colour;
- nonSpecialColumns[nonSpecialColumns.Count - 1 - i].AccentColour = colour;
+ single.Judgements.Scale = Scale;
}
}
public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
{
var maniaObject = (ManiaHitObject)judgedObject.HitObject;
- columns[maniaObject.Column].OnJudgement(judgedObject, judgement);
+ int column = maniaObject.Column;
+ Columns[maniaObject.Column].OnJudgement(judgedObject, judgement);
- judgements.Clear();
- judgements.Add(new DrawableManiaJudgement(judgement)
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- });
- }
-
- ///
- /// Whether the column index is a special column for this playfield.
- ///
- /// The 0-based column index.
- /// Whether the column is a special column.
- private bool isSpecialColumn(int column)
- {
- switch (SpecialColumnPosition)
- {
- default:
- case SpecialColumnPosition.Normal:
- return columnCount % 2 == 1 && column == columnCount / 2;
- case SpecialColumnPosition.Left:
- return column == 0;
- case SpecialColumnPosition.Right:
- return column == columnCount - 1;
- }
+ getFallDownControlContainerByActualColumn(column).AddJudgement(judgement);
}
public override void Add(DrawableHitObject h) => Columns.ElementAt(((ManiaHitObject)h.HitObject).Column).Add(h);
- public void Add(DrawableBarLine barline) => HitObjects.Add(barline);
-
- protected override void Update()
+ public void Add(BarLine barline)
{
- // Due to masking differences, it is not possible to get the width of the columns container automatically
- // While masking on effectively only the Y-axis, so we need to set the width of the bar line container manually
- content.Width = columns.Width;
+ //HitObjects.Add(new DrawableBarLine(barline));
+ foreach (var single in ListColumnGroup)
+ {
+ single.HitObjects.Add(new DrawableBarLine(barline));
+ }
+ }
+
+ private ManiaColumnGroup getFallDownControlContainerByActualColumn(int actualColumn)
+ {
+ int sum = 0;
+ foreach (var single in ListColumnGroup)
+ {
+ sum = sum + single.ColumnCount;
+ if (sum > actualColumn)
+ {
+ return single;
+ }
+ }
+
+ return null;
}
}
}
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
index 61446a31b6..7ea9382314 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
@@ -24,6 +24,7 @@ using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Timing;
using osu.Game.Rulesets.UI;
+using osu.Game.Rulesets.Mania.Mods;
namespace osu.Game.Rulesets.Mania.UI
{
@@ -35,7 +36,12 @@ namespace osu.Game.Rulesets.Mania.UI
///
public int AvailableColumns { get; private set; }
- public IEnumerable BarLines;
+ ///
+ /// Co-op
+ ///
+ public bool Coop { get; set; } = false;
+
+ public IEnumerable BarLines;
public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
: base(ruleset, beatmap, isForCurrentRuleset)
@@ -44,7 +50,7 @@ namespace osu.Game.Rulesets.Mania.UI
double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue;
var timingPoints = Beatmap.ControlPointInfo.TimingPoints;
- var barLines = new List();
+ var barLines = new List();
for (int i = 0; i < timingPoints.Count; i++)
{
@@ -56,12 +62,12 @@ namespace osu.Game.Rulesets.Mania.UI
int index = 0;
for (double t = timingPoints[i].Time; Precision.DefinitelyBigger(endTime, t); t += point.BeatLength, index++)
{
- barLines.Add(new DrawableBarLine(new BarLine
+ barLines.Add(new BarLine
{
StartTime = t,
ControlPoint = point,
BeatIndex = index
- }));
+ });
}
}
@@ -74,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.UI
BarLines.ForEach(Playfield.Add);
}
- protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(AvailableColumns)
+ protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(AvailableColumns, Coop)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -101,6 +107,20 @@ namespace osu.Game.Rulesets.Mania.UI
AvailableColumns = Math.Max(4, Math.Min((int)Math.Round(WorkingBeatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty) + 1, 7));
}
+ //get mods to change column and coop
+ foreach (var single in this.WorkingBeatmap.Mods.Value)
+ {
+ if (single is ManiaKeyMod maniaKeyMod)
+ {
+ AvailableColumns = maniaKeyMod.KeyCount;
+ }
+ if (single is ManiaModKeyCoop)
+ {
+ Coop = true;
+ AvailableColumns = AvailableColumns * 2;
+ }
+ }
+
return new ManiaBeatmapConverter(IsForCurrentRuleset, AvailableColumns);
}
diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
index bdd6656ed9..564af6e454 100644
--- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
+++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
@@ -92,6 +92,7 @@
+