mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 23:36:10 +08:00
Merge remote-tracking branch 'upstream/master' into RefactorInputQueues
This commit is contained in:
commit
9b33499fe7
@ -1 +1 @@
|
|||||||
Subproject commit 80bcb82ef8d2e1af1ce077f4a037b6d279ad9e74
|
Subproject commit 2c595626a3da0a28ca9cd46c4639b63ff37d5b5a
|
@ -45,7 +45,7 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
protected override string LocateBasePath()
|
protected override string LocateBasePath()
|
||||||
{
|
{
|
||||||
Func<string, bool> checkExists = p => Directory.Exists(Path.Combine(p, "Songs"));
|
bool checkExists(string p) => Directory.Exists(Path.Combine(p, "Songs"));
|
||||||
|
|
||||||
string stableInstallPath;
|
string stableInstallPath;
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ namespace osu.Desktop
|
|||||||
host.Run(new OsuGameDesktop(args));
|
host.Run(new OsuGameDesktop(args));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Beatmaps
|
namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||||
{
|
{
|
||||||
internal class CatchBeatmapConverter : BeatmapConverter<CatchHitObject>
|
public class CatchBeatmapConverter : BeatmapConverter<CatchHitObject>
|
||||||
{
|
{
|
||||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
||||||
|
|
||||||
@ -20,6 +20,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
var curveData = obj as IHasCurve;
|
var curveData = obj as IHasCurve;
|
||||||
var positionData = obj as IHasXPosition;
|
var positionData = obj as IHasXPosition;
|
||||||
var comboData = obj as IHasCombo;
|
var comboData = obj as IHasCombo;
|
||||||
|
var endTime = obj as IHasEndTime;
|
||||||
|
|
||||||
if (positionData == null)
|
if (positionData == null)
|
||||||
yield break;
|
yield break;
|
||||||
@ -42,6 +43,19 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (endTime != null)
|
||||||
|
{
|
||||||
|
yield return new BananaShower
|
||||||
|
{
|
||||||
|
StartTime = obj.StartTime,
|
||||||
|
Samples = obj.Samples,
|
||||||
|
Duration = endTime.Duration,
|
||||||
|
NewCombo = comboData?.NewCombo ?? false
|
||||||
|
};
|
||||||
|
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
yield return new Fruit
|
yield return new Fruit
|
||||||
{
|
{
|
||||||
StartTime = obj.StartTime,
|
StartTime = obj.StartTime,
|
||||||
|
@ -12,14 +12,14 @@ using OpenTK;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Beatmaps
|
namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||||
{
|
{
|
||||||
internal class CatchBeatmapProcessor : BeatmapProcessor<CatchHitObject>
|
public class CatchBeatmapProcessor : BeatmapProcessor<CatchHitObject>
|
||||||
{
|
{
|
||||||
public override void PostProcess(Beatmap<CatchHitObject> beatmap)
|
public override void PostProcess(Beatmap<CatchHitObject> beatmap)
|
||||||
{
|
{
|
||||||
if (beatmap.ComboColors.Count == 0)
|
if (beatmap.ComboColors.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int comboIndex = 0;
|
int index = 0;
|
||||||
int colourIndex = 0;
|
int colourIndex = 0;
|
||||||
|
|
||||||
CatchHitObject lastObj = null;
|
CatchHitObject lastObj = null;
|
||||||
@ -31,12 +31,10 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
if (obj.NewCombo)
|
if (obj.NewCombo)
|
||||||
{
|
{
|
||||||
if (lastObj != null) lastObj.LastInCombo = true;
|
if (lastObj != null) lastObj.LastInCombo = true;
|
||||||
|
|
||||||
comboIndex = 0;
|
|
||||||
colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
|
colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.ComboIndex = comboIndex++;
|
obj.IndexInBeatmap = index++;
|
||||||
obj.ComboColour = beatmap.ComboColors[colourIndex];
|
obj.ComboColour = beatmap.ComboColors[colourIndex];
|
||||||
|
|
||||||
lastObj = obj;
|
lastObj = obj;
|
||||||
|
@ -22,6 +22,7 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
[Description("Move right")]
|
[Description("Move right")]
|
||||||
MoveRight,
|
MoveRight,
|
||||||
[Description("Engage dash")]
|
[Description("Engage dash")]
|
||||||
Dash
|
Dash,
|
||||||
|
PositionUpdate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
{
|
{
|
||||||
Mods = new Mod[]
|
Mods = new Mod[]
|
||||||
{
|
{
|
||||||
new ModAutoplay(),
|
new CatchModAutoplay(),
|
||||||
new ModCinema(),
|
new ModCinema(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
|
|
||||||
public override int LegacyID => 2;
|
public override int LegacyID => 2;
|
||||||
|
|
||||||
public CatchRuleset(RulesetInfo rulesetInfo)
|
public CatchRuleset(RulesetInfo rulesetInfo = null)
|
||||||
: base(rulesetInfo)
|
: base(rulesetInfo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Mods
|
|
||||||
{
|
|
||||||
public class CatchModNoFail : ModNoFail
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModEasy : ModEasy
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModHidden : ModHidden
|
|
||||||
{
|
|
||||||
public override string Description => @"Play with fading notes for a slight score advantage.";
|
|
||||||
public override double ScoreMultiplier => 1.06;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModHardRock : ModHardRock
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.12;
|
|
||||||
public override bool Ranked => true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModSuddenDeath : ModSuddenDeath
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModDaycore : ModDaycore
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModDoubleTime : ModDoubleTime
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.06;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModRelax : ModRelax
|
|
||||||
{
|
|
||||||
public override string Description => @"Use the mouse to control the catcher.";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModHalfTime : ModHalfTime
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModNightcore : ModNightcore
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.06;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModFlashlight : ModFlashlight
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.12;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CatchModPerfect : ModPerfect
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
24
osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs
Normal file
24
osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Catch.Replays;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModAutoplay : ModAutoplay<CatchHitObject>
|
||||||
|
{
|
||||||
|
protected override Score CreateReplayScore(Beatmap<CatchHitObject> beatmap)
|
||||||
|
{
|
||||||
|
return new Score
|
||||||
|
{
|
||||||
|
User = new User { Username = "osu!salad!" },
|
||||||
|
Replay = new CatchAutoGenerator(beatmap).Generate(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs
Normal file
12
osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModDaycore : ModDaycore
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 0.5;
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs
Normal file
12
osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModDoubleTime : ModDoubleTime
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.06;
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs
Normal file
11
osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModEasy : ModEasy
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs
Normal file
12
osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModFlashlight : ModFlashlight
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.12;
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs
Normal file
12
osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModHalfTime : ModHalfTime
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 0.5;
|
||||||
|
}
|
||||||
|
}
|
13
osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
Normal file
13
osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModHardRock : ModHardRock
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.12;
|
||||||
|
public override bool Ranked => true;
|
||||||
|
}
|
||||||
|
}
|
13
osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs
Normal file
13
osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModHidden : ModHidden
|
||||||
|
{
|
||||||
|
public override string Description => @"Play with fading notes for a slight score advantage.";
|
||||||
|
public override double ScoreMultiplier => 1.06;
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs
Normal file
12
osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModNightcore : ModNightcore
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.06;
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs
Normal file
11
osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModNoFail : ModNoFail
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs
Normal file
11
osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModPerfect : ModPerfect
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs
Normal file
12
osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModRelax : ModRelax
|
||||||
|
{
|
||||||
|
public override string Description => @"Use the mouse to control the catcher.";
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs
Normal file
11
osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModSuddenDeath : ModSuddenDeath
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
63
osu.Game.Rulesets.Catch/Objects/BananaShower.cs
Normal file
63
osu.Game.Rulesets.Catch/Objects/BananaShower.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Objects
|
||||||
|
{
|
||||||
|
public class BananaShower : CatchHitObject, IHasEndTime
|
||||||
|
{
|
||||||
|
public override FruitVisualRepresentation VisualRepresentation => FruitVisualRepresentation.Banana;
|
||||||
|
|
||||||
|
public override bool LastInCombo => true;
|
||||||
|
|
||||||
|
protected override void CreateNestedHitObjects()
|
||||||
|
{
|
||||||
|
base.CreateNestedHitObjects();
|
||||||
|
createBananas();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createBananas()
|
||||||
|
{
|
||||||
|
double spacing = Duration;
|
||||||
|
while (spacing > 100)
|
||||||
|
spacing /= 2;
|
||||||
|
|
||||||
|
if (spacing <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (double i = StartTime; i <= EndTime; i += spacing)
|
||||||
|
AddNested(new Banana
|
||||||
|
{
|
||||||
|
Samples = Samples,
|
||||||
|
ComboColour = getNextComboColour(),
|
||||||
|
StartTime = i,
|
||||||
|
X = RNG.NextSingle()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color4 getNextComboColour()
|
||||||
|
{
|
||||||
|
switch (RNG.Next(0, 3))
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return new Color4(255, 240, 0, 255);
|
||||||
|
case 1:
|
||||||
|
return new Color4(255, 192, 0, 255);
|
||||||
|
case 2:
|
||||||
|
return new Color4(214, 221, 28, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double EndTime => StartTime + Duration;
|
||||||
|
|
||||||
|
public double Duration { get; set; }
|
||||||
|
|
||||||
|
public class Banana : Fruit
|
||||||
|
{
|
||||||
|
public override FruitVisualRepresentation VisualRepresentation => FruitVisualRepresentation.Banana;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,8 +15,11 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
|
|
||||||
public float X { get; set; }
|
public float X { get; set; }
|
||||||
|
|
||||||
public Color4 ComboColour { get; set; } = Color4.Gray;
|
public Color4 ComboColour { get; set; }
|
||||||
public int ComboIndex { get; set; }
|
|
||||||
|
public int IndexInBeatmap { get; set; }
|
||||||
|
|
||||||
|
public virtual FruitVisualRepresentation VisualRepresentation => (FruitVisualRepresentation)(IndexInBeatmap % 4);
|
||||||
|
|
||||||
public virtual bool NewCombo { get; set; }
|
public virtual bool NewCombo { get; set; }
|
||||||
|
|
||||||
@ -44,4 +47,13 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
Scale = 1.0f - 0.7f * (difficulty.CircleSize - 5) / 5;
|
Scale = 1.0f - 0.7f * (difficulty.CircleSize - 5) / 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum FruitVisualRepresentation
|
||||||
|
{
|
||||||
|
Pear,
|
||||||
|
Grape,
|
||||||
|
Raspberry,
|
||||||
|
Pineapple,
|
||||||
|
Banana // banananananannaanana
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
|
{
|
||||||
|
public class DrawableBananaShower : DrawableCatchHitObject<BananaShower>
|
||||||
|
{
|
||||||
|
private readonly Container bananaContainer;
|
||||||
|
|
||||||
|
public DrawableBananaShower(BananaShower s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation = null)
|
||||||
|
: base(s)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
Origin = Anchor.BottomLeft;
|
||||||
|
X = 0;
|
||||||
|
|
||||||
|
Child = bananaContainer = new Container { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
|
foreach (var b in s.NestedHitObjects.Cast<BananaShower.Banana>())
|
||||||
|
AddNested(getVisualRepresentation?.Invoke(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||||
|
{
|
||||||
|
if (timeOffset >= 0)
|
||||||
|
AddJudgement(new Judgement { Result = NestedHitObjects.Cast<DrawableCatchHitObject>().Any(n => n.Judgements.Any(j => j.IsHit)) ? HitResult.Perfect : HitResult.Miss });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void AddNested(DrawableHitObject h)
|
||||||
|
{
|
||||||
|
((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false;
|
||||||
|
bananaContainer.Add(h);
|
||||||
|
base.AddNested(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,11 +5,24 @@ using System;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
{
|
{
|
||||||
|
public abstract class PalpableCatchHitObject<TObject> : DrawableCatchHitObject<TObject>
|
||||||
|
where TObject : CatchHitObject
|
||||||
|
{
|
||||||
|
public override bool CanBePlated => true;
|
||||||
|
|
||||||
|
protected PalpableCatchHitObject(TObject hitObject)
|
||||||
|
: base(hitObject)
|
||||||
|
{
|
||||||
|
Scale = new Vector2(HitObject.Scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class DrawableCatchHitObject<TObject> : DrawableCatchHitObject
|
public abstract class DrawableCatchHitObject<TObject> : DrawableCatchHitObject
|
||||||
where TObject : CatchHitObject
|
where TObject : CatchHitObject
|
||||||
{
|
{
|
||||||
@ -19,27 +32,29 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
HitObject = hitObject;
|
HitObject = hitObject;
|
||||||
|
Anchor = Anchor.BottomLeft;
|
||||||
Scale = new Vector2(HitObject.Scale);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class DrawableCatchHitObject : DrawableScrollingHitObject<CatchHitObject>
|
public abstract class DrawableCatchHitObject : DrawableHitObject<CatchHitObject>
|
||||||
{
|
{
|
||||||
|
public virtual bool CanBePlated => false;
|
||||||
|
|
||||||
protected DrawableCatchHitObject(CatchHitObject hitObject)
|
protected DrawableCatchHitObject(CatchHitObject hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
RelativePositionAxes = Axes.Both;
|
RelativePositionAxes = Axes.X;
|
||||||
X = hitObject.X;
|
X = hitObject.X;
|
||||||
Y = (float)HitObject.StartTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Func<CatchHitObject, bool> CheckPosition;
|
public Func<CatchHitObject, bool> CheckPosition;
|
||||||
|
|
||||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||||
{
|
{
|
||||||
|
if (CheckPosition == null) return;
|
||||||
|
|
||||||
if (timeOffset > 0)
|
if (timeOffset > 0)
|
||||||
AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss });
|
AddJudgement(new Judgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss });
|
||||||
}
|
}
|
||||||
|
|
||||||
private const float preempt = 1000;
|
private const float preempt = 1000;
|
||||||
@ -47,17 +62,21 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
protected override void UpdateState(ArmedState state)
|
protected override void UpdateState(ArmedState state)
|
||||||
{
|
{
|
||||||
using (BeginAbsoluteSequence(HitObject.StartTime - preempt))
|
using (BeginAbsoluteSequence(HitObject.StartTime - preempt))
|
||||||
{
|
|
||||||
// animation
|
|
||||||
this.FadeIn(200);
|
this.FadeIn(200);
|
||||||
}
|
|
||||||
|
|
||||||
switch (state)
|
var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;
|
||||||
|
|
||||||
|
using (BeginAbsoluteSequence(endTime, true))
|
||||||
{
|
{
|
||||||
case ArmedState.Miss:
|
switch (state)
|
||||||
using (BeginAbsoluteSequence(HitObject.StartTime, true))
|
{
|
||||||
this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out);
|
case ArmedState.Miss:
|
||||||
break;
|
this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out).Expire();
|
||||||
|
break;
|
||||||
|
case ArmedState.Hit:
|
||||||
|
this.FadeOut().Expire();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,13 @@ using OpenTK;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
{
|
{
|
||||||
public class DrawableDroplet : DrawableCatchHitObject<Droplet>
|
public class DrawableDroplet : PalpableCatchHitObject<Droplet>
|
||||||
{
|
{
|
||||||
public DrawableDroplet(Droplet h)
|
public DrawableDroplet(Droplet h)
|
||||||
: base(h)
|
: base(h)
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS) / 4;
|
||||||
Size = new Vector2(Pulp.PULP_SIZE);
|
|
||||||
|
|
||||||
AccentColour = h.ComboColour;
|
AccentColour = h.ComboColour;
|
||||||
Masking = false;
|
Masking = false;
|
||||||
}
|
}
|
||||||
@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
Child = new Pulp
|
Child = new Pulp
|
||||||
{
|
{
|
||||||
AccentColour = AccentColour,
|
AccentColour = AccentColour,
|
||||||
Scale = new Vector2(0.8f),
|
Size = Size
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
@ -11,14 +14,16 @@ using OpenTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
{
|
{
|
||||||
public class DrawableFruit : DrawableCatchHitObject<Fruit>
|
public class DrawableFruit : PalpableCatchHitObject<Fruit>
|
||||||
{
|
{
|
||||||
|
private Circle border;
|
||||||
|
|
||||||
public DrawableFruit(Fruit h)
|
public DrawableFruit(Fruit h)
|
||||||
: base(h)
|
: base(h)
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
Size = new Vector2(Pulp.PULP_SIZE * 2.2f, Pulp.PULP_SIZE * 2.8f);
|
Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS);
|
||||||
AccentColour = HitObject.ComboColour;
|
AccentColour = HitObject.ComboColour;
|
||||||
Masking = false;
|
Masking = false;
|
||||||
|
|
||||||
@ -28,48 +33,34 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
Children = new Framework.Graphics.Drawable[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
//todo: share this more
|
createPulp(HitObject.VisualRepresentation),
|
||||||
new BufferedContainer
|
border = new Circle
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
EdgeEffect = new EdgeEffectParameters
|
||||||
CacheDrawnFrameBuffer = true,
|
{
|
||||||
|
Hollow = !HitObject.HyperDash,
|
||||||
|
Type = EdgeEffectType.Glow,
|
||||||
|
Radius = 4,
|
||||||
|
Colour = HitObject.HyperDash ? Color4.Red : AccentColour.Darken(1).Opacity(0.6f)
|
||||||
|
},
|
||||||
|
Size = new Vector2(Height * 1.5f),
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
BorderColour = Color4.White,
|
||||||
|
BorderThickness = 4f,
|
||||||
Children = new Framework.Graphics.Drawable[]
|
Children = new Framework.Graphics.Drawable[]
|
||||||
{
|
{
|
||||||
new Pulp
|
new Box
|
||||||
{
|
{
|
||||||
RelativePositionAxes = Axes.Both,
|
AlwaysPresent = true,
|
||||||
Anchor = Anchor.TopCentre,
|
Colour = AccentColour,
|
||||||
Origin = Anchor.TopCentre,
|
Alpha = 0,
|
||||||
AccentColour = AccentColour,
|
RelativeSizeAxes = Axes.Both
|
||||||
Scale = new Vector2(0.6f),
|
}
|
||||||
},
|
|
||||||
new Pulp
|
|
||||||
{
|
|
||||||
RelativePositionAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.CentreLeft,
|
|
||||||
Origin = Anchor.CentreLeft,
|
|
||||||
AccentColour = AccentColour,
|
|
||||||
Y = -0.08f
|
|
||||||
},
|
|
||||||
new Pulp
|
|
||||||
{
|
|
||||||
RelativePositionAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.CentreRight,
|
|
||||||
Origin = Anchor.CentreRight,
|
|
||||||
AccentColour = AccentColour,
|
|
||||||
Y = -0.08f
|
|
||||||
},
|
|
||||||
new Pulp
|
|
||||||
{
|
|
||||||
RelativePositionAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.BottomCentre,
|
|
||||||
Origin = Anchor.BottomCentre,
|
|
||||||
AccentColour = AccentColour,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (HitObject.HyperDash)
|
if (HitObject.HyperDash)
|
||||||
@ -82,9 +73,205 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
AccentColour = Color4.Red,
|
AccentColour = Color4.Red,
|
||||||
Blending = BlendingMode.Additive,
|
Blending = BlendingMode.Additive,
|
||||||
Alpha = 0.5f,
|
Alpha = 0.5f,
|
||||||
Scale = new Vector2(2)
|
Scale = new Vector2(1.333f)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation)
|
||||||
|
{
|
||||||
|
const float large_pulp_3 = 13f;
|
||||||
|
const float distance_from_centre_3 = 0.23f;
|
||||||
|
|
||||||
|
const float large_pulp_4 = large_pulp_3 * 0.925f;
|
||||||
|
const float distance_from_centre_4 = distance_from_centre_3 / 0.925f;
|
||||||
|
|
||||||
|
const float small_pulp = large_pulp_3 / 2;
|
||||||
|
|
||||||
|
Vector2 positionAt(float angle, float distance) => new Vector2(
|
||||||
|
distance * (float)Math.Sin(angle * Math.PI / 180),
|
||||||
|
distance * (float)Math.Cos(angle * Math.PI / 180));
|
||||||
|
|
||||||
|
switch (representation)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return new Container();
|
||||||
|
case FruitVisualRepresentation.Raspberry:
|
||||||
|
return new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Framework.Graphics.Drawable[]
|
||||||
|
{
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(small_pulp),
|
||||||
|
Y = 0.05f,
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_4),
|
||||||
|
Position = positionAt(0, distance_from_centre_4),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_4),
|
||||||
|
Position = positionAt(90, distance_from_centre_4),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_4),
|
||||||
|
Position = positionAt(180, distance_from_centre_4),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
Size = new Vector2(large_pulp_4),
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Position = positionAt(270, distance_from_centre_4),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case FruitVisualRepresentation.Pineapple:
|
||||||
|
return new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Framework.Graphics.Drawable[]
|
||||||
|
{
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.BottomCentre,
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(small_pulp),
|
||||||
|
Y = 0.1f,
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_4),
|
||||||
|
Position = positionAt(45, distance_from_centre_4),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_4),
|
||||||
|
Position = positionAt(135, distance_from_centre_4),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_4),
|
||||||
|
Position = positionAt(225, distance_from_centre_4),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
Size = new Vector2(large_pulp_4),
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Position = positionAt(315, distance_from_centre_4),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case FruitVisualRepresentation.Pear:
|
||||||
|
return new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Framework.Graphics.Drawable[]
|
||||||
|
{
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(small_pulp),
|
||||||
|
Y = -0.1f,
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_3),
|
||||||
|
Position = positionAt(60, distance_from_centre_3),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_3),
|
||||||
|
Position = positionAt(180, distance_from_centre_3),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
Size = new Vector2(large_pulp_3),
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Position = positionAt(300, distance_from_centre_3),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case FruitVisualRepresentation.Grape:
|
||||||
|
return new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Framework.Graphics.Drawable[]
|
||||||
|
{
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(small_pulp),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_3),
|
||||||
|
Position = positionAt(0, distance_from_centre_3),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_3),
|
||||||
|
Position = positionAt(120, distance_from_centre_3),
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
Size = new Vector2(large_pulp_3),
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Position = positionAt(240, distance_from_centre_3),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case FruitVisualRepresentation.Banana:
|
||||||
|
return new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Framework.Graphics.Drawable[]
|
||||||
|
{
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(small_pulp),
|
||||||
|
Y = -0.15f
|
||||||
|
},
|
||||||
|
new Pulp
|
||||||
|
{
|
||||||
|
AccentColour = AccentColour,
|
||||||
|
Size = new Vector2(large_pulp_4 * 1.2f, large_pulp_4 * 3),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
border.Alpha = (float)MathHelper.Clamp((HitObject.StartTime - Time.Current) / 500, 0, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using OpenTK;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
@ -13,41 +13,26 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
{
|
{
|
||||||
private readonly Container dropletContainer;
|
private readonly Container dropletContainer;
|
||||||
|
|
||||||
public DrawableJuiceStream(JuiceStream s) : base(s)
|
public DrawableJuiceStream(JuiceStream s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation = null)
|
||||||
|
: base(s)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
Height = (float)HitObject.Duration;
|
Origin = Anchor.BottomLeft;
|
||||||
X = 0;
|
X = 0;
|
||||||
|
|
||||||
Child = dropletContainer = new Container
|
Child = dropletContainer = new Container { RelativeSizeAxes = Axes.Both, };
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime),
|
|
||||||
RelativeChildSize = new Vector2(1, (float)HitObject.Duration)
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (CatchHitObject tick in s.NestedHitObjects.OfType<CatchHitObject>())
|
foreach (var o in s.NestedHitObjects.Cast<CatchHitObject>())
|
||||||
{
|
AddNested(getVisualRepresentation?.Invoke(o));
|
||||||
TinyDroplet tiny = tick as TinyDroplet;
|
|
||||||
if (tiny != null)
|
|
||||||
{
|
|
||||||
AddNested(new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) });
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Droplet droplet = tick as Droplet;
|
|
||||||
if (droplet != null)
|
|
||||||
AddNested(new DrawableDroplet(droplet));
|
|
||||||
|
|
||||||
Fruit fruit = tick as Fruit;
|
|
||||||
if (fruit != null)
|
|
||||||
AddNested(new DrawableFruit(fruit));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AddNested(DrawableHitObject<CatchHitObject> h)
|
protected override void AddNested(DrawableHitObject h)
|
||||||
{
|
{
|
||||||
((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false;
|
var catchObject = (DrawableCatchHitObject)h;
|
||||||
|
|
||||||
|
catchObject.CheckPosition = o => CheckPosition?.Invoke(o) ?? false;
|
||||||
|
catchObject.AccentColour = HitObject.ComboColour;
|
||||||
|
|
||||||
dropletContainer.Add(h);
|
dropletContainer.Add(h);
|
||||||
base.AddNested(h);
|
base.AddNested(h);
|
||||||
}
|
}
|
||||||
|
@ -6,18 +6,17 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using OpenTK;
|
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
|
||||||
{
|
{
|
||||||
public class Pulp : Circle, IHasAccentColour
|
public class Pulp : Circle, IHasAccentColour
|
||||||
{
|
{
|
||||||
public const float PULP_SIZE = (float)CatchHitObject.OBJECT_RADIUS / 2.2f;
|
|
||||||
|
|
||||||
public Pulp()
|
public Pulp()
|
||||||
{
|
{
|
||||||
Size = new Vector2(PULP_SIZE);
|
RelativePositionAxes = Axes.Both;
|
||||||
|
Anchor = Anchor.Centre;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
Blending = BlendingMode.Additive;
|
Blending = BlendingMode.Additive;
|
||||||
Colour = Color4.White.Opacity(0.9f);
|
Colour = Color4.White.Opacity(0.9f);
|
||||||
@ -34,8 +33,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
|
|||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
Radius = 5,
|
Radius = 8,
|
||||||
Colour = accentColour.Lighten(100),
|
Colour = accentColour.Darken(0.2f).Opacity(0.75f)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,10 +125,8 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
|
X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity;
|
public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity;
|
||||||
|
|
||||||
public float EndX => Curve.PositionAt(ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH;
|
public float EndX => Curve.PositionAt(ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH;
|
||||||
|
54
osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs
Normal file
54
osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Replays
|
||||||
|
{
|
||||||
|
internal class CatchAutoGenerator : AutoGenerator<CatchHitObject>
|
||||||
|
{
|
||||||
|
public const double RELEASE_DELAY = 20;
|
||||||
|
|
||||||
|
public CatchAutoGenerator(Beatmap<CatchHitObject> beatmap)
|
||||||
|
: base(beatmap)
|
||||||
|
{
|
||||||
|
Replay = new Replay { User = new User { Username = @"Autoplay" } };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Replay Replay;
|
||||||
|
|
||||||
|
public override Replay Generate()
|
||||||
|
{
|
||||||
|
// Todo: Realistically this shouldn't be needed, but the first frame is skipped with the way replays are currently handled
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(-100000, 0));
|
||||||
|
|
||||||
|
foreach (var obj in Beatmap.HitObjects)
|
||||||
|
{
|
||||||
|
switch (obj)
|
||||||
|
{
|
||||||
|
case Fruit _:
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(obj.StartTime, obj.X));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var nestedObj in obj.NestedHitObjects.Cast<CatchHitObject>())
|
||||||
|
{
|
||||||
|
switch (nestedObj)
|
||||||
|
{
|
||||||
|
case BananaShower.Banana _:
|
||||||
|
case TinyDroplet _:
|
||||||
|
case Droplet _:
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(nestedObj.StartTime, nestedObj.X));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Replay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Replays
|
||||||
|
{
|
||||||
|
public class CatchFramedReplayInputHandler : FramedReplayInputHandler
|
||||||
|
{
|
||||||
|
public CatchFramedReplayInputHandler(Replay replay)
|
||||||
|
: base(replay)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override List<InputState> GetPendingStates() => new List<InputState>
|
||||||
|
{
|
||||||
|
new CatchReplayState
|
||||||
|
{
|
||||||
|
PressedActions = new List<CatchAction> { CatchAction.PositionUpdate },
|
||||||
|
CatcherX = ((CatchReplayFrame)CurrentFrame).MouseX
|
||||||
|
},
|
||||||
|
new CatchReplayState { PressedActions = new List<CatchAction>() },
|
||||||
|
};
|
||||||
|
|
||||||
|
public class CatchReplayState : ReplayState<CatchAction>
|
||||||
|
{
|
||||||
|
public float? CatcherX { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs
Normal file
17
osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Replays
|
||||||
|
{
|
||||||
|
public class CatchReplayFrame : ReplayFrame
|
||||||
|
{
|
||||||
|
public override bool IsImportant => MouseX > 0;
|
||||||
|
|
||||||
|
public CatchReplayFrame(double time, float? x = null)
|
||||||
|
: base(time, x ?? -1, null, ReplayButtonState.None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.UI;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Scoring
|
namespace osu.Game.Rulesets.Catch.Scoring
|
||||||
{
|
{
|
||||||
internal class CatchScoreProcessor : ScoreProcessor<CatchHitObject>
|
public class CatchScoreProcessor : ScoreProcessor<CatchHitObject>
|
||||||
{
|
{
|
||||||
public CatchScoreProcessor(RulesetContainer<CatchHitObject> rulesetContainer)
|
public CatchScoreProcessor(RulesetContainer<CatchHitObject> rulesetContainer)
|
||||||
: base(rulesetContainer)
|
: base(rulesetContainer)
|
||||||
@ -21,23 +21,25 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
|||||||
{
|
{
|
||||||
foreach (var obj in beatmap.HitObjects)
|
foreach (var obj in beatmap.HitObjects)
|
||||||
{
|
{
|
||||||
var stream = obj as JuiceStream;
|
switch (obj)
|
||||||
|
|
||||||
if (stream != null)
|
|
||||||
{
|
{
|
||||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
case JuiceStream stream:
|
||||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
|
|
||||||
foreach (var unused in stream.NestedHitObjects.OfType<CatchHitObject>())
|
|
||||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
|
|
||||||
continue;
|
foreach (var _ in stream.NestedHitObjects.Cast<CatchHitObject>())
|
||||||
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
|
break;
|
||||||
|
case BananaShower shower:
|
||||||
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
|
|
||||||
|
foreach (var _ in shower.NestedHitObjects.Cast<CatchHitObject>())
|
||||||
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
|
break;
|
||||||
|
case Fruit _:
|
||||||
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fruit = obj as Fruit;
|
|
||||||
|
|
||||||
if (fruit != null)
|
|
||||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base.SimulateAutoplay(beatmap);
|
base.SimulateAutoplay(beatmap);
|
||||||
|
50
osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs
Normal file
50
osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||||
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
[Ignore("getting CI working")]
|
||||||
|
public class TestCaseBananaShower : Game.Tests.Visual.TestCasePlayer
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(BananaShower),
|
||||||
|
typeof(DrawableBananaShower),
|
||||||
|
|
||||||
|
typeof(CatchRuleset),
|
||||||
|
typeof(CatchRulesetContainer),
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestCaseBananaShower()
|
||||||
|
: base(new CatchRuleset())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Beatmap CreateBeatmap()
|
||||||
|
{
|
||||||
|
var beatmap = new Beatmap
|
||||||
|
{
|
||||||
|
BeatmapInfo = new BeatmapInfo
|
||||||
|
{
|
||||||
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
CircleSize = 6,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
beatmap.HitObjects.Add(new BananaShower { StartTime = 200, Duration = 5000, NewCombo = true });
|
||||||
|
|
||||||
|
return beatmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
[Ignore("getting CI working")]
|
[Ignore("getting CI working")]
|
||||||
public class TestCaseCatchPlayer : Game.Tests.Visual.TestCasePlayer
|
public class TestCaseCatchPlayer : Game.Tests.Visual.TestCasePlayer
|
||||||
{
|
{
|
||||||
public TestCaseCatchPlayer() : base(typeof(CatchRuleset))
|
public TestCaseCatchPlayer() : base(new CatchRuleset())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer
|
public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer
|
||||||
{
|
{
|
||||||
public TestCaseCatchStacker()
|
public TestCaseCatchStacker()
|
||||||
: base(typeof(CatchRuleset))
|
: base(new CatchRuleset())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
104
osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs
Normal file
104
osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
|
{
|
||||||
|
[Ignore("getting CI working")]
|
||||||
|
public class TestCaseFruitObjects : OsuTestCase
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(CatchHitObject),
|
||||||
|
typeof(Fruit),
|
||||||
|
typeof(Droplet),
|
||||||
|
typeof(DrawableCatchHitObject),
|
||||||
|
typeof(DrawableFruit),
|
||||||
|
typeof(DrawableDroplet),
|
||||||
|
typeof(Pulp),
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestCaseFruitObjects()
|
||||||
|
{
|
||||||
|
Add(new GridContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Content = new[]
|
||||||
|
{
|
||||||
|
new Drawable[]
|
||||||
|
{
|
||||||
|
createDrawable(0),
|
||||||
|
createDrawable(1),
|
||||||
|
createDrawable(2),
|
||||||
|
},
|
||||||
|
new Drawable[]
|
||||||
|
{
|
||||||
|
createDrawable(3),
|
||||||
|
createDrawable(4),
|
||||||
|
createDrawable(5),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private DrawableFruit createDrawable(int index)
|
||||||
|
{
|
||||||
|
var fruit = new Fruit
|
||||||
|
{
|
||||||
|
StartTime = 1000000000000,
|
||||||
|
IndexInBeatmap = index,
|
||||||
|
Scale = 1.5f,
|
||||||
|
};
|
||||||
|
|
||||||
|
fruit.ComboColour = colourForRrepesentation(fruit.VisualRepresentation);
|
||||||
|
|
||||||
|
return new DrawableFruit(fruit)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
RelativePositionAxes = Axes.Both,
|
||||||
|
Position = Vector2.Zero,
|
||||||
|
Alpha = 1,
|
||||||
|
LifetimeStart = double.NegativeInfinity,
|
||||||
|
LifetimeEnd = double.PositiveInfinity,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color4 colourForRrepesentation(FruitVisualRepresentation representation)
|
||||||
|
{
|
||||||
|
switch (representation)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case FruitVisualRepresentation.Pear:
|
||||||
|
return new Color4(17, 136, 170, 255);
|
||||||
|
case FruitVisualRepresentation.Grape:
|
||||||
|
return new Color4(204, 102, 0, 255);
|
||||||
|
case FruitVisualRepresentation.Raspberry:
|
||||||
|
return new Color4(121, 9, 13, 255);
|
||||||
|
case FruitVisualRepresentation.Pineapple:
|
||||||
|
return new Color4(102, 136, 0, 255);
|
||||||
|
case FruitVisualRepresentation.Banana:
|
||||||
|
switch (RNG.Next(0, 3))
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return new Color4(255, 240, 0, 255);
|
||||||
|
case 1:
|
||||||
|
return new Color4(255, 192, 0, 255);
|
||||||
|
case 2:
|
||||||
|
return new Color4(214, 221, 28, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
public class TestCaseHyperdash : Game.Tests.Visual.TestCasePlayer
|
public class TestCaseHyperdash : Game.Tests.Visual.TestCasePlayer
|
||||||
{
|
{
|
||||||
public TestCaseHyperdash()
|
public TestCaseHyperdash()
|
||||||
: base(typeof(CatchRuleset))
|
: base(new CatchRuleset())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints
|
public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints
|
||||||
{
|
{
|
||||||
public TestCasePerformancePoints()
|
public TestCasePerformancePoints()
|
||||||
: base(new CatchRuleset(new RulesetInfo()))
|
: base(new CatchRuleset())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
using OpenTK;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.UI
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
{
|
{
|
||||||
@ -22,17 +22,18 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
private readonly CatcherArea catcherArea;
|
private readonly CatcherArea catcherArea;
|
||||||
|
|
||||||
public CatchPlayfield(BeatmapDifficulty difficulty)
|
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
|
||||||
: base(Axes.Y)
|
: base(ScrollingDirection.Down, BASE_WIDTH)
|
||||||
{
|
{
|
||||||
Container explodingFruitContainer;
|
Container explodingFruitContainer;
|
||||||
|
|
||||||
Reversed.Value = true;
|
|
||||||
|
|
||||||
Anchor = Anchor.TopCentre;
|
Anchor = Anchor.TopCentre;
|
||||||
Origin = Anchor.TopCentre;
|
Origin = Anchor.TopCentre;
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
ScaledContent.Anchor = Anchor.BottomLeft;
|
||||||
|
ScaledContent.Origin = Anchor.BottomLeft;
|
||||||
|
|
||||||
|
ScaledContent.AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
content = new Container<Drawable>
|
content = new Container<Drawable>
|
||||||
{
|
{
|
||||||
@ -44,11 +45,12 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
},
|
},
|
||||||
catcherArea = new CatcherArea(difficulty)
|
catcherArea = new CatcherArea(difficulty)
|
||||||
{
|
{
|
||||||
|
GetVisualRepresentation = getVisualRepresentation,
|
||||||
ExplodingFruitTarget = explodingFruitContainer,
|
ExplodingFruitTarget = explodingFruitContainer,
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.TopLeft,
|
Origin = Anchor.TopLeft,
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj);
|
public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj);
|
||||||
@ -56,6 +58,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
public override void Add(DrawableHitObject h)
|
public override void Add(DrawableHitObject h)
|
||||||
{
|
{
|
||||||
h.Depth = (float)h.HitObject.StartTime;
|
h.Depth = (float)h.HitObject.StartTime;
|
||||||
|
h.OnJudgement += onJudgement;
|
||||||
|
|
||||||
base.Add(h);
|
base.Add(h);
|
||||||
|
|
||||||
@ -63,18 +66,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
fruit.CheckPosition = CheckIfWeCanCatch;
|
fruit.CheckPosition = CheckIfWeCanCatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement);
|
||||||
{
|
|
||||||
if (judgement.IsHit)
|
|
||||||
{
|
|
||||||
Vector2 screenPosition = judgedObject.ScreenSpaceDrawQuad.Centre;
|
|
||||||
|
|
||||||
// todo: don't do this
|
|
||||||
(judgedObject.Parent as Container<DrawableHitObject>)?.Remove(judgedObject);
|
|
||||||
(judgedObject.Parent as Container)?.Remove(judgedObject);
|
|
||||||
|
|
||||||
catcherArea.Add(judgedObject, screenPosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,14 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||||
|
using osu.Game.Rulesets.Catch.Replays;
|
||||||
using osu.Game.Rulesets.Catch.Scoring;
|
using osu.Game.Rulesets.Catch.Scoring;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.UI
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
{
|
{
|
||||||
@ -22,23 +26,31 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);
|
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);
|
||||||
|
|
||||||
|
protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
|
||||||
|
|
||||||
protected override BeatmapProcessor<CatchHitObject> CreateBeatmapProcessor() => new CatchBeatmapProcessor();
|
protected override BeatmapProcessor<CatchHitObject> CreateBeatmapProcessor() => new CatchBeatmapProcessor();
|
||||||
|
|
||||||
protected override BeatmapConverter<CatchHitObject> CreateBeatmapConverter() => new CatchBeatmapConverter();
|
protected override BeatmapConverter<CatchHitObject> CreateBeatmapConverter() => new CatchBeatmapConverter();
|
||||||
|
|
||||||
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty);
|
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, GetVisualRepresentation);
|
||||||
|
|
||||||
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
|
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
|
||||||
|
|
||||||
protected override DrawableHitObject<CatchHitObject> GetVisualRepresentation(CatchHitObject h)
|
protected override DrawableHitObject<CatchHitObject> GetVisualRepresentation(CatchHitObject h)
|
||||||
{
|
{
|
||||||
var fruit = h as Fruit;
|
switch (h)
|
||||||
if (fruit != null)
|
{
|
||||||
return new DrawableFruit(fruit);
|
case Fruit fruit:
|
||||||
|
return new DrawableFruit(fruit);
|
||||||
var stream = h as JuiceStream;
|
case JuiceStream stream:
|
||||||
if (stream != null)
|
return new DrawableJuiceStream(stream, GetVisualRepresentation);
|
||||||
return new DrawableJuiceStream(stream);
|
case BananaShower banana:
|
||||||
|
return new DrawableBananaShower(banana, GetVisualRepresentation);
|
||||||
|
case TinyDroplet tiny:
|
||||||
|
return new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) };
|
||||||
|
case Droplet droplet:
|
||||||
|
return new DrawableDroplet(droplet);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -12,18 +12,23 @@ using osu.Framework.Input.Bindings;
|
|||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||||
|
using osu.Game.Rulesets.Catch.Replays;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.UI
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
{
|
{
|
||||||
public class CatcherArea : Container
|
public class CatcherArea : Container, IKeyBindingHandler<CatchAction>
|
||||||
{
|
{
|
||||||
public const float CATCHER_SIZE = 172;
|
public const float CATCHER_SIZE = 172;
|
||||||
|
|
||||||
protected readonly Catcher MovableCatcher;
|
protected readonly Catcher MovableCatcher;
|
||||||
|
|
||||||
|
public Func<CatchHitObject, DrawableHitObject<CatchHitObject>> GetVisualRepresentation;
|
||||||
|
|
||||||
public Container ExplodingFruitTarget
|
public Container ExplodingFruitTarget
|
||||||
{
|
{
|
||||||
set { MovableCatcher.ExplodingFruitTarget = value; }
|
set { MovableCatcher.ExplodingFruitTarget = value; }
|
||||||
@ -39,19 +44,60 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(DrawableHitObject fruit, Vector2 absolutePosition)
|
private DrawableCatchHitObject lastPlateableFruit;
|
||||||
|
|
||||||
|
public void OnJudgement(DrawableCatchHitObject fruit, Judgement judgement)
|
||||||
{
|
{
|
||||||
fruit.RelativePositionAxes = Axes.None;
|
if (judgement.IsHit && fruit.CanBePlated)
|
||||||
fruit.Position = new Vector2(MovableCatcher.ToLocalSpace(absolutePosition).X - MovableCatcher.DrawSize.X / 2, 0);
|
{
|
||||||
|
var caughtFruit = (DrawableCatchHitObject)GetVisualRepresentation?.Invoke(fruit.HitObject);
|
||||||
|
|
||||||
fruit.Anchor = Anchor.TopCentre;
|
if (caughtFruit == null) return;
|
||||||
fruit.Origin = Anchor.BottomCentre;
|
|
||||||
fruit.Scale *= 0.7f;
|
|
||||||
fruit.LifetimeEnd = double.MaxValue;
|
|
||||||
|
|
||||||
MovableCatcher.Add(fruit);
|
caughtFruit.AccentColour = fruit.AccentColour;
|
||||||
|
caughtFruit.RelativePositionAxes = Axes.None;
|
||||||
|
caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(fruit.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0);
|
||||||
|
|
||||||
|
caughtFruit.Anchor = Anchor.TopCentre;
|
||||||
|
caughtFruit.Origin = Anchor.Centre;
|
||||||
|
caughtFruit.Scale *= 0.7f;
|
||||||
|
caughtFruit.LifetimeEnd = double.MaxValue;
|
||||||
|
|
||||||
|
MovableCatcher.Add(caughtFruit);
|
||||||
|
|
||||||
|
lastPlateableFruit = caughtFruit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fruit.HitObject.LastInCombo)
|
||||||
|
{
|
||||||
|
if (judgement.IsHit)
|
||||||
|
{
|
||||||
|
// this is required to make this run after the last caught fruit runs UpdateState at least once.
|
||||||
|
// TODO: find a better alternative
|
||||||
|
if (lastPlateableFruit.IsLoaded)
|
||||||
|
MovableCatcher.Explode();
|
||||||
|
else
|
||||||
|
lastPlateableFruit.OnLoadComplete = _ => { MovableCatcher.Explode(); };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MovableCatcher.Drop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool OnPressed(CatchAction action)
|
||||||
|
{
|
||||||
|
if (action != CatchAction.PositionUpdate) return false;
|
||||||
|
|
||||||
|
CatchFramedReplayInputHandler.CatchReplayState state = (CatchFramedReplayInputHandler.CatchReplayState)GetContainingInputManager().CurrentState;
|
||||||
|
|
||||||
|
if (state.CatcherX.HasValue)
|
||||||
|
MovableCatcher.X = state.CatcherX.Value;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnReleased(CatchAction action) => false;
|
||||||
|
|
||||||
public bool AttemptCatch(CatchHitObject obj) => MovableCatcher.AttemptCatch(obj);
|
public bool AttemptCatch(CatchHitObject obj) => MovableCatcher.AttemptCatch(obj);
|
||||||
|
|
||||||
public class Catcher : Container, IKeyBindingHandler<CatchAction>
|
public class Catcher : Container, IKeyBindingHandler<CatchAction>
|
||||||
@ -84,12 +130,12 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
createCatcherSprite(),
|
|
||||||
caughtFruit = new Container<DrawableHitObject>
|
caughtFruit = new Container<DrawableHitObject>
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.BottomCentre,
|
Origin = Anchor.BottomCentre,
|
||||||
}
|
},
|
||||||
|
createCatcherSprite(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,20 +213,23 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
/// <param name="fruit">The fruit that was caught.</param>
|
/// <param name="fruit">The fruit that was caught.</param>
|
||||||
public void Add(DrawableHitObject fruit)
|
public void Add(DrawableHitObject fruit)
|
||||||
{
|
{
|
||||||
float distance = fruit.DrawSize.X / 2 * fruit.Scale.X;
|
float ourRadius = fruit.DrawSize.X / 2 * fruit.Scale.X;
|
||||||
|
float theirRadius = 0;
|
||||||
|
|
||||||
while (caughtFruit.Any(f => f.LifetimeEnd == double.MaxValue && Vector2Extensions.DistanceSquared(f.Position, fruit.Position) < distance * distance))
|
const float allowance = 6;
|
||||||
|
|
||||||
|
while (caughtFruit.Any(f =>
|
||||||
|
f.LifetimeEnd == double.MaxValue &&
|
||||||
|
Vector2Extensions.Distance(f.Position, fruit.Position) < (ourRadius + (theirRadius = f.DrawSize.X / 2 * f.Scale.X)) / (allowance / 2)))
|
||||||
{
|
{
|
||||||
fruit.X += RNG.Next(-5, 5);
|
float diff = (ourRadius + theirRadius) / allowance;
|
||||||
fruit.Y -= RNG.Next(0, 5);
|
fruit.X += (RNG.NextSingle() - 0.5f) * 2 * diff;
|
||||||
|
fruit.Y -= RNG.NextSingle() * diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fruit.X = MathHelper.Clamp(fruit.X, -CATCHER_SIZE / 2, CATCHER_SIZE / 2);
|
||||||
|
|
||||||
caughtFruit.Add(fruit);
|
caughtFruit.Add(fruit);
|
||||||
|
|
||||||
var catchObject = (CatchHitObject)fruit.HitObject;
|
|
||||||
|
|
||||||
if (catchObject.LastInCombo)
|
|
||||||
explode();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -190,15 +239,15 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
/// <returns>Whether the catch is possible.</returns>
|
/// <returns>Whether the catch is possible.</returns>
|
||||||
public bool AttemptCatch(CatchHitObject fruit)
|
public bool AttemptCatch(CatchHitObject fruit)
|
||||||
{
|
{
|
||||||
const double relative_catcher_width = CATCHER_SIZE / 2;
|
double halfCatcherWidth = CATCHER_SIZE * Math.Abs(Scale.X) * 0.5f;
|
||||||
|
|
||||||
// this stuff wil disappear once we move fruit to non-relative coordinate space in the future.
|
// this stuff wil disappear once we move fruit to non-relative coordinate space in the future.
|
||||||
var catchObjectPosition = fruit.X * CatchPlayfield.BASE_WIDTH;
|
var catchObjectPosition = fruit.X * CatchPlayfield.BASE_WIDTH;
|
||||||
var catcherPosition = Position.X * CatchPlayfield.BASE_WIDTH;
|
var catcherPosition = Position.X * CatchPlayfield.BASE_WIDTH;
|
||||||
|
|
||||||
var validCatch =
|
var validCatch =
|
||||||
catchObjectPosition >= catcherPosition - relative_catcher_width / 2 &&
|
catchObjectPosition >= catcherPosition - halfCatcherWidth &&
|
||||||
catchObjectPosition <= catcherPosition + relative_catcher_width / 2;
|
catchObjectPosition <= catcherPosition + halfCatcherWidth;
|
||||||
|
|
||||||
if (validCatch && fruit.HyperDash)
|
if (validCatch && fruit.HyperDash)
|
||||||
{
|
{
|
||||||
@ -309,7 +358,35 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * BASE_SPEED * dashModifier, 0, 1);
|
X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * BASE_SPEED * dashModifier, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void explode()
|
/// <summary>
|
||||||
|
/// Drop any fruit off the plate.
|
||||||
|
/// </summary>
|
||||||
|
public void Drop()
|
||||||
|
{
|
||||||
|
var fruit = caughtFruit.ToArray();
|
||||||
|
|
||||||
|
foreach (var f in fruit)
|
||||||
|
{
|
||||||
|
if (ExplodingFruitTarget != null)
|
||||||
|
{
|
||||||
|
f.Anchor = Anchor.TopLeft;
|
||||||
|
f.Position = caughtFruit.ToSpaceOfOtherDrawable(f.DrawPosition, ExplodingFruitTarget);
|
||||||
|
|
||||||
|
caughtFruit.Remove(f);
|
||||||
|
|
||||||
|
ExplodingFruitTarget.Add(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
f.MoveToY(f.Y + 75, 750, Easing.InSine);
|
||||||
|
f.FadeOut(750);
|
||||||
|
f.Expire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Explode any fruit off the plate.
|
||||||
|
/// </summary>
|
||||||
|
public void Explode()
|
||||||
{
|
{
|
||||||
var fruit = caughtFruit.ToArray();
|
var fruit = caughtFruit.ToArray();
|
||||||
|
|
||||||
|
@ -49,11 +49,28 @@
|
|||||||
<Compile Include="Beatmaps\CatchBeatmapProcessor.cs" />
|
<Compile Include="Beatmaps\CatchBeatmapProcessor.cs" />
|
||||||
<Compile Include="CatchDifficultyCalculator.cs" />
|
<Compile Include="CatchDifficultyCalculator.cs" />
|
||||||
<Compile Include="CatchInputManager.cs" />
|
<Compile Include="CatchInputManager.cs" />
|
||||||
|
<Compile Include="Mods\CatchModDaycore.cs" />
|
||||||
|
<Compile Include="Mods\CatchModDoubleTime.cs" />
|
||||||
|
<Compile Include="Mods\CatchModEasy.cs" />
|
||||||
|
<Compile Include="Mods\CatchModFlashlight.cs" />
|
||||||
|
<Compile Include="Mods\CatchModHalfTime.cs" />
|
||||||
|
<Compile Include="Mods\CatchModHardRock.cs" />
|
||||||
|
<Compile Include="Mods\CatchModHidden.cs" />
|
||||||
|
<Compile Include="Mods\CatchModNightcore.cs" />
|
||||||
|
<Compile Include="Mods\CatchModPerfect.cs" />
|
||||||
|
<Compile Include="Mods\CatchModRelax.cs" />
|
||||||
|
<Compile Include="Mods\CatchModSuddenDeath.cs" />
|
||||||
|
<Compile Include="Mods\CatchModAutoplay.cs" />
|
||||||
|
<Compile Include="Objects\BananaShower.cs" />
|
||||||
|
<Compile Include="Objects\Drawable\DrawableBananaShower.cs" />
|
||||||
<Compile Include="Objects\Drawable\DrawableCatchHitObject.cs" />
|
<Compile Include="Objects\Drawable\DrawableCatchHitObject.cs" />
|
||||||
<Compile Include="Objects\Drawable\DrawableDroplet.cs" />
|
<Compile Include="Objects\Drawable\DrawableDroplet.cs" />
|
||||||
<Compile Include="Objects\Drawable\DrawableJuiceStream.cs" />
|
<Compile Include="Objects\Drawable\DrawableJuiceStream.cs" />
|
||||||
<Compile Include="Objects\Drawable\Pieces\Pulp.cs" />
|
<Compile Include="Objects\Drawable\Pieces\Pulp.cs" />
|
||||||
<Compile Include="Objects\JuiceStream.cs" />
|
<Compile Include="Objects\JuiceStream.cs" />
|
||||||
|
<Compile Include="Replays\CatchAutoGenerator.cs" />
|
||||||
|
<Compile Include="Replays\CatchFramedReplayInputHandler.cs" />
|
||||||
|
<Compile Include="Replays\CatchReplayFrame.cs" />
|
||||||
<Compile Include="Scoring\CatchScoreProcessor.cs" />
|
<Compile Include="Scoring\CatchScoreProcessor.cs" />
|
||||||
<Compile Include="Judgements\CatchJudgement.cs" />
|
<Compile Include="Judgements\CatchJudgement.cs" />
|
||||||
<Compile Include="Objects\CatchHitObject.cs" />
|
<Compile Include="Objects\CatchHitObject.cs" />
|
||||||
@ -62,8 +79,10 @@
|
|||||||
<Compile Include="Objects\Fruit.cs" />
|
<Compile Include="Objects\Fruit.cs" />
|
||||||
<Compile Include="Objects\TinyDroplet.cs" />
|
<Compile Include="Objects\TinyDroplet.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Tests\TestCaseBananaShower.cs" />
|
||||||
<Compile Include="Tests\TestCaseCatcherArea.cs" />
|
<Compile Include="Tests\TestCaseCatcherArea.cs" />
|
||||||
<Compile Include="Tests\TestCaseCatchStacker.cs" />
|
<Compile Include="Tests\TestCaseCatchStacker.cs" />
|
||||||
|
<Compile Include="Tests\TestCaseFruitObjects.cs" />
|
||||||
<Compile Include="Tests\TestCasePerformancePoints.cs" />
|
<Compile Include="Tests\TestCasePerformancePoints.cs" />
|
||||||
<Compile Include="Tests\TestCaseCatchPlayer.cs" />
|
<Compile Include="Tests\TestCaseCatchPlayer.cs" />
|
||||||
<Compile Include="Tests\TestCaseHyperdash.cs" />
|
<Compile Include="Tests\TestCaseHyperdash.cs" />
|
||||||
@ -71,7 +90,7 @@
|
|||||||
<Compile Include="UI\CatchRulesetContainer.cs" />
|
<Compile Include="UI\CatchRulesetContainer.cs" />
|
||||||
<Compile Include="UI\CatchPlayfield.cs" />
|
<Compile Include="UI\CatchPlayfield.cs" />
|
||||||
<Compile Include="CatchRuleset.cs" />
|
<Compile Include="CatchRuleset.cs" />
|
||||||
<Compile Include="Mods\CatchMod.cs" />
|
<Compile Include="Mods\CatchModNoFail.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.config" />
|
<None Include="app.config" />
|
||||||
|
@ -58,7 +58,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
|
|
||||||
protected override Beatmap<ManiaHitObject> ConvertBeatmap(Beatmap original)
|
protected override Beatmap<ManiaHitObject> ConvertBeatmap(Beatmap original)
|
||||||
{
|
{
|
||||||
|
|
||||||
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
||||||
|
|
||||||
int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate);
|
int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate);
|
||||||
|
@ -321,7 +321,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Func<SampleInfo, bool> isDoubleSample = sample => sample.Name == SampleInfo.HIT_CLAP && sample.Name == SampleInfo.HIT_FINISH;
|
bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP && sample.Name == SampleInfo.HIT_FINISH;
|
||||||
|
|
||||||
bool canGenerateTwoNotes = (convertType & PatternType.LowProbability) == 0;
|
bool canGenerateTwoNotes = (convertType & PatternType.LowProbability) == 0;
|
||||||
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample);
|
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample);
|
||||||
|
@ -95,7 +95,6 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
new ModCinema(),
|
new ModCinema(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
new ManiaModGravity()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -113,7 +112,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
|
|
||||||
public override int LegacyID => 3;
|
public override int LegacyID => 3;
|
||||||
|
|
||||||
public ManiaRuleset(RulesetInfo rulesetInfo)
|
public ManiaRuleset(RulesetInfo rulesetInfo = null)
|
||||||
: base(rulesetInfo)
|
: base(rulesetInfo)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.Timing;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A type of mod which generates speed adjustments that scroll the hit objects and bar lines.
|
|
||||||
/// </summary>
|
|
||||||
internal interface IGenerateSpeedAdjustments
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Applies this mod to a hit renderer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="rulesetContainer">The hit renderer to apply to.</param>
|
|
||||||
/// <param name="hitObjectTimingChanges">The per-column list of speed adjustments for hit objects.</param>
|
|
||||||
/// <param name="barlineTimingChanges">The list of speed adjustments for bar lines.</param>
|
|
||||||
void ApplyToRulesetContainer(ManiaRulesetContainer rulesetContainer, ref List<SpeedAdjustmentContainer>[] hitObjectTimingChanges, ref List<SpeedAdjustmentContainer> barlineTimingChanges);
|
|
||||||
}
|
|
||||||
}
|
|
29
osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
Normal file
29
osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public abstract class ManiaKeyMod : Mod, IApplicableToBeatmapConverter<ManiaHitObject>
|
||||||
|
{
|
||||||
|
public override string ShortenedName => Name;
|
||||||
|
public abstract int KeyCount { get; }
|
||||||
|
public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier
|
||||||
|
public override bool Ranked => true;
|
||||||
|
|
||||||
|
public void ApplyToBeatmapConverter(BeatmapConverter<ManiaHitObject> beatmapConverter)
|
||||||
|
{
|
||||||
|
var mbc = (ManiaBeatmapConverter)beatmapConverter;
|
||||||
|
|
||||||
|
// Although this can work, for now let's not allow keymods for mania-specific beatmaps
|
||||||
|
if (mbc.IsForCurrentRuleset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mbc.TargetColumns = KeyCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,197 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
|
||||||
using osu.Framework.MathUtils;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
|
||||||
using osu.Game.Rulesets.Mania.Replays;
|
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Users;
|
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
|
||||||
{
|
|
||||||
public class ManiaModNoFail : ModNoFail
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModEasy : ModEasy
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModHidden : ModHidden
|
|
||||||
{
|
|
||||||
public override string Description => @"The notes fade out before you hit them!";
|
|
||||||
public override double ScoreMultiplier => 1.0;
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModHardRock : ModHardRock
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModSuddenDeath : ModSuddenDeath
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModDaycore : ModDaycore
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 0.3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModDoubleTime : ModDoubleTime
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModHalfTime : ModHalfTime
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 0.3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModNightcore : ModNightcore
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModFlashlight : ModFlashlight
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.0;
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModHidden) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModPerfect : ModPerfect
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModFadeIn : Mod
|
|
||||||
{
|
|
||||||
public override string Name => "FadeIn";
|
|
||||||
public override string ShortenedName => "FI";
|
|
||||||
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
|
|
||||||
public override ModType Type => ModType.DifficultyIncrease;
|
|
||||||
public override double ScoreMultiplier => 1;
|
|
||||||
public override bool Ranked => true;
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModRandom : Mod, IApplicableToRulesetContainer<ManiaHitObject>
|
|
||||||
{
|
|
||||||
public override string Name => "Random";
|
|
||||||
public override string ShortenedName => "RD";
|
|
||||||
public override FontAwesome Icon => FontAwesome.fa_osu_dice;
|
|
||||||
public override string Description => @"Shuffle around the notes!";
|
|
||||||
public override double ScoreMultiplier => 1;
|
|
||||||
|
|
||||||
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
|
||||||
{
|
|
||||||
int availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns;
|
|
||||||
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList();
|
|
||||||
|
|
||||||
rulesetContainer.Objects.OfType<ManiaHitObject>().ForEach(h => h.Column = shuffledColumns[h.Column]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class ManiaKeyMod : Mod, IApplicableMod, IApplicableToBeatmapConverter<ManiaHitObject>
|
|
||||||
{
|
|
||||||
public override string ShortenedName => Name;
|
|
||||||
public abstract int KeyCount { get; }
|
|
||||||
public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier
|
|
||||||
public override bool Ranked => true;
|
|
||||||
|
|
||||||
public void ApplyToBeatmapConverter(BeatmapConverter<ManiaHitObject> beatmapConverter)
|
|
||||||
{
|
|
||||||
var mbc = (ManiaBeatmapConverter)beatmapConverter;
|
|
||||||
|
|
||||||
// Although this can work, for now let's not allow keymods for mania-specific beatmaps
|
|
||||||
if (mbc.IsForCurrentRuleset)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mbc.TargetColumns = KeyCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKey1 : ManiaKeyMod
|
|
||||||
{
|
|
||||||
public override int KeyCount => 1;
|
|
||||||
public override string Name => "1K";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKey2 : ManiaKeyMod
|
|
||||||
{
|
|
||||||
public override int KeyCount => 2;
|
|
||||||
public override string Name => "2K";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKey3 : ManiaKeyMod
|
|
||||||
{
|
|
||||||
public override int KeyCount => 3;
|
|
||||||
public override string Name => "3K";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKey4 : ManiaKeyMod
|
|
||||||
{
|
|
||||||
public override int KeyCount => 4;
|
|
||||||
public override string Name => "4K";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKey5 : ManiaKeyMod
|
|
||||||
{
|
|
||||||
public override int KeyCount => 5;
|
|
||||||
public override string Name => "5K";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKey6 : ManiaKeyMod
|
|
||||||
{
|
|
||||||
public override int KeyCount => 6;
|
|
||||||
public override string Name => "6K";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKey7 : ManiaKeyMod
|
|
||||||
{
|
|
||||||
public override int KeyCount => 7;
|
|
||||||
public override string Name => "7K";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKey8 : ManiaKeyMod
|
|
||||||
{
|
|
||||||
public override int KeyCount => 8;
|
|
||||||
public override string Name => "8K";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKey9 : ManiaKeyMod
|
|
||||||
{
|
|
||||||
public override int KeyCount => 9;
|
|
||||||
public override string Name => "9K";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModKeyCoop : Mod
|
|
||||||
{
|
|
||||||
public override string Name => "KeyCoop";
|
|
||||||
public override string ShortenedName => "2P";
|
|
||||||
public override string Description => @"Double the key amount, double the fun!";
|
|
||||||
public override double ScoreMultiplier => 1;
|
|
||||||
public override bool Ranked => true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ManiaModAutoplay : ModAutoplay<ManiaHitObject>
|
|
||||||
{
|
|
||||||
protected override Score CreateReplayScore(Beatmap<ManiaHitObject> beatmap) => new Score
|
|
||||||
{
|
|
||||||
User = new User { Username = "osu!topus!" },
|
|
||||||
Replay = new ManiaAutoGenerator(beatmap).Generate(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
24
osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs
Normal file
24
osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.Replays;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModAutoplay : ModAutoplay<ManiaHitObject>
|
||||||
|
{
|
||||||
|
protected override Score CreateReplayScore(Beatmap<ManiaHitObject> beatmap)
|
||||||
|
{
|
||||||
|
return new Score
|
||||||
|
{
|
||||||
|
User = new User { Username = "osu!topus!" },
|
||||||
|
Replay = new ManiaAutoGenerator(beatmap).Generate(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs
Normal file
12
osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModDaycore : ModDaycore
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 0.3;
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs
Normal file
12
osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModDoubleTime : ModDoubleTime
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.0;
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModEasy : ModEasy
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
20
osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs
Normal file
20
osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModFadeIn : Mod
|
||||||
|
{
|
||||||
|
public override string Name => "FadeIn";
|
||||||
|
public override string ShortenedName => "FI";
|
||||||
|
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
|
||||||
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
|
public override double ScoreMultiplier => 1;
|
||||||
|
public override bool Ranked => true;
|
||||||
|
public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) };
|
||||||
|
}
|
||||||
|
}
|
14
osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs
Normal file
14
osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModFlashlight : ModFlashlight
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.0;
|
||||||
|
public override Type[] IncompatibleMods => new[] { typeof(ModHidden) };
|
||||||
|
}
|
||||||
|
}
|
@ -1,48 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Mania.Timing;
|
|
||||||
using osu.Game.Rulesets.Timing;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
|
||||||
{
|
|
||||||
public class ManiaModGravity : Mod, IGenerateSpeedAdjustments
|
|
||||||
{
|
|
||||||
public override string Name => "Gravity";
|
|
||||||
public override string ShortenedName => "GR";
|
|
||||||
|
|
||||||
public override double ScoreMultiplier => 0;
|
|
||||||
|
|
||||||
public override FontAwesome Icon => FontAwesome.fa_sort_desc;
|
|
||||||
|
|
||||||
public void ApplyToRulesetContainer(ManiaRulesetContainer rulesetContainer, ref List<SpeedAdjustmentContainer>[] hitObjectTimingChanges, ref List<SpeedAdjustmentContainer> barlineTimingChanges)
|
|
||||||
{
|
|
||||||
// We have to generate one speed adjustment per hit object for gravity
|
|
||||||
foreach (ManiaHitObject obj in rulesetContainer.Objects.OfType<ManiaHitObject>())
|
|
||||||
{
|
|
||||||
MultiplierControlPoint controlPoint = rulesetContainer.CreateControlPointAt(obj.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;
|
|
||||||
|
|
||||||
hitObjectTimingChanges[obj.Column].Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Like with hit objects, we need to generate one speed adjustment per bar line
|
|
||||||
foreach (DrawableBarLine barLine in rulesetContainer.BarLines)
|
|
||||||
{
|
|
||||||
var controlPoint = rulesetContainer.CreateControlPointAt(barLine.HitObject.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;
|
|
||||||
|
|
||||||
barlineTimingChanges.Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
12
osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs
Normal file
12
osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModHalfTime : ModHalfTime
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 0.3;
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs
Normal file
12
osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModHardRock : ModHardRock
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.0;
|
||||||
|
}
|
||||||
|
}
|
15
osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs
Normal file
15
osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModHidden : ModHidden
|
||||||
|
{
|
||||||
|
public override string Description => @"The notes fade out before you hit them!";
|
||||||
|
public override double ScoreMultiplier => 1.0;
|
||||||
|
public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) };
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKey1 : ManiaKeyMod
|
||||||
|
{
|
||||||
|
public override int KeyCount => 1;
|
||||||
|
public override string Name => "1K";
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKey2 : ManiaKeyMod
|
||||||
|
{
|
||||||
|
public override int KeyCount => 2;
|
||||||
|
public override string Name => "2K";
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKey3 : ManiaKeyMod
|
||||||
|
{
|
||||||
|
public override int KeyCount => 3;
|
||||||
|
public override string Name => "3K";
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKey4 : ManiaKeyMod
|
||||||
|
{
|
||||||
|
public override int KeyCount => 4;
|
||||||
|
public override string Name => "4K";
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKey5 : ManiaKeyMod
|
||||||
|
{
|
||||||
|
public override int KeyCount => 5;
|
||||||
|
public override string Name => "5K";
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKey6 : ManiaKeyMod
|
||||||
|
{
|
||||||
|
public override int KeyCount => 6;
|
||||||
|
public override string Name => "6K";
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKey7 : ManiaKeyMod
|
||||||
|
{
|
||||||
|
public override int KeyCount => 7;
|
||||||
|
public override string Name => "7K";
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKey8 : ManiaKeyMod
|
||||||
|
{
|
||||||
|
public override int KeyCount => 8;
|
||||||
|
public override string Name => "8K";
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKey9 : ManiaKeyMod
|
||||||
|
{
|
||||||
|
public override int KeyCount => 9;
|
||||||
|
public override string Name => "9K";
|
||||||
|
}
|
||||||
|
}
|
16
osu.Game.Rulesets.Mania/Mods/ManiaModKeyCoop.cs
Normal file
16
osu.Game.Rulesets.Mania/Mods/ManiaModKeyCoop.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModKeyCoop : Mod
|
||||||
|
{
|
||||||
|
public override string Name => "KeyCoop";
|
||||||
|
public override string ShortenedName => "2P";
|
||||||
|
public override string Description => @"Double the key amount, double the fun!";
|
||||||
|
public override double ScoreMultiplier => 1;
|
||||||
|
public override bool Ranked => true;
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs
Normal file
12
osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModNightcore : ModNightcore
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.0;
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModNoFail : ModNoFail
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModPerfect : ModPerfect
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
31
osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs
Normal file
31
osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModRandom : Mod, IApplicableToRulesetContainer<ManiaHitObject>
|
||||||
|
{
|
||||||
|
public override string Name => "Random";
|
||||||
|
public override string ShortenedName => "RD";
|
||||||
|
public override FontAwesome Icon => FontAwesome.fa_osu_dice;
|
||||||
|
public override string Description => @"Shuffle around the notes!";
|
||||||
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
|
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
||||||
|
{
|
||||||
|
var availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns;
|
||||||
|
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList();
|
||||||
|
|
||||||
|
rulesetContainer.Objects.OfType<ManiaHitObject>().ForEach(h => h.Column = shuffledColumns[h.Column]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModSuddenDeath : ModSuddenDeath
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,6 @@ using osu.Game.Rulesets.Objects.Drawables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Mania.Judgements;
|
using osu.Game.Rulesets.Mania.Judgements;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
@ -42,8 +41,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
public DrawableHoldNote(HoldNote hitObject, ManiaAction action)
|
public DrawableHoldNote(HoldNote hitObject, ManiaAction action)
|
||||||
: base(hitObject, action)
|
: base(hitObject, action)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.X;
|
||||||
Height = (float)HitObject.Duration;
|
|
||||||
|
|
||||||
AddRange(new Drawable[]
|
AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
@ -60,12 +58,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
},
|
},
|
||||||
tickContainer = new Container<DrawableHoldNoteTick>
|
tickContainer = new Container<DrawableHoldNoteTick> { RelativeSizeAxes = Axes.Both },
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime),
|
|
||||||
RelativeChildSize = new Vector2(1, (float)HitObject.Duration)
|
|
||||||
},
|
|
||||||
head = new DrawableHeadNote(this, action)
|
head = new DrawableHeadNote(this, action)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
@ -73,7 +66,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
},
|
},
|
||||||
tail = new DrawableTailNote(this, action)
|
tail = new DrawableTailNote(this, action)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre
|
Origin = Anchor.TopCentre
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -157,7 +150,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
holdStartTime = null;
|
holdStartTime = null;
|
||||||
|
|
||||||
// If the key has been released too early, the user should not receive full score for the release
|
// If the key has been released too early, the user should not receive full score for the release
|
||||||
if (!tail.AllJudged)
|
if (!tail.IsHit)
|
||||||
hasBroken = true;
|
hasBroken = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -175,13 +168,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
this.holdNote = holdNote;
|
this.holdNote = holdNote;
|
||||||
|
|
||||||
RelativePositionAxes = Axes.None;
|
|
||||||
Y = 0;
|
|
||||||
|
|
||||||
// Life time managed by the parent DrawableHoldNote
|
|
||||||
LifetimeStart = double.MinValue;
|
|
||||||
LifetimeEnd = double.MaxValue;
|
|
||||||
|
|
||||||
GlowPiece.Alpha = 0;
|
GlowPiece.Alpha = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,6 +186,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void UpdateState(ArmedState state)
|
||||||
|
{
|
||||||
|
// The holdnote keeps scrolling through for now, so having the head disappear looks weird
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -214,13 +205,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
this.holdNote = holdNote;
|
this.holdNote = holdNote;
|
||||||
|
|
||||||
RelativePositionAxes = Axes.None;
|
|
||||||
Y = 0;
|
|
||||||
|
|
||||||
// Life time managed by the parent DrawableHoldNote
|
|
||||||
LifetimeStart = double.MinValue;
|
|
||||||
LifetimeEnd = double.MaxValue;
|
|
||||||
|
|
||||||
GlowPiece.Alpha = 0;
|
GlowPiece.Alpha = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,6 +236,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void UpdateState(ArmedState state)
|
||||||
|
{
|
||||||
|
// The holdnote keeps scrolling through, so having the tail disappear looks weird
|
||||||
|
}
|
||||||
|
|
||||||
public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down
|
public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down
|
||||||
|
|
||||||
public override bool OnReleased(ManiaAction action)
|
public override bool OnReleased(ManiaAction action)
|
||||||
|
@ -32,15 +32,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
Anchor = Anchor.TopCentre;
|
Anchor = Anchor.TopCentre;
|
||||||
Origin = Anchor.TopCentre;
|
Origin = Anchor.TopCentre;
|
||||||
|
|
||||||
Y = (float)HitObject.StartTime;
|
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Size = new Vector2(1);
|
Size = new Vector2(1);
|
||||||
|
|
||||||
// Life time managed by the parent DrawableHoldNote
|
|
||||||
LifetimeStart = double.MinValue;
|
|
||||||
LifetimeEnd = double.MaxValue;
|
|
||||||
|
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
glowContainer = new CircularContainer
|
glowContainer = new CircularContainer
|
||||||
|
@ -7,7 +7,7 @@ using osu.Game.Rulesets.Objects.Drawables;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||||
{
|
{
|
||||||
public abstract class DrawableManiaHitObject<TObject> : DrawableScrollingHitObject<ManiaHitObject>
|
public abstract class DrawableManiaHitObject<TObject> : DrawableHitObject<ManiaHitObject>
|
||||||
where TObject : ManiaHitObject
|
where TObject : ManiaHitObject
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -20,7 +20,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null)
|
protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
RelativePositionAxes = Axes.Y;
|
Anchor = Anchor.TopCentre;
|
||||||
|
Origin = Anchor.TopCentre;
|
||||||
|
|
||||||
HitObject = hitObject;
|
HitObject = hitObject;
|
||||||
|
|
||||||
if (action != null)
|
if (action != null)
|
||||||
|
@ -78,6 +78,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
protected override void UpdateState(ArmedState state)
|
protected override void UpdateState(ArmedState state)
|
||||||
{
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case ArmedState.Hit:
|
||||||
|
case ArmedState.Miss:
|
||||||
|
this.FadeOut(100).Expire();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool OnPressed(ManiaAction action)
|
public virtual bool OnPressed(ManiaAction action)
|
||||||
|
@ -93,7 +93,6 @@ namespace osu.Game.Rulesets.Mania.Objects
|
|||||||
Column = Column
|
Column = Column
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -5,16 +5,13 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Rulesets.Mania.Judgements;
|
using osu.Game.Rulesets.Mania.Judgements;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Mania.Timing;
|
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Timing;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Tests
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
@ -44,10 +41,10 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
AddStep("Right special style", () => createPlayfield(8, SpecialColumnPosition.Right));
|
AddStep("Right special style", () => createPlayfield(8, SpecialColumnPosition.Right));
|
||||||
AddStep("Reversed", () => createPlayfield(4, SpecialColumnPosition.Normal, true));
|
AddStep("Reversed", () => createPlayfield(4, SpecialColumnPosition.Normal, true));
|
||||||
|
|
||||||
AddStep("Notes with input", () => createPlayfieldWithNotes(false));
|
AddStep("Notes with input", () => createPlayfieldWithNotes());
|
||||||
AddStep("Notes with input (reversed)", () => createPlayfieldWithNotes(false, true));
|
AddStep("Notes with input (reversed)", () => createPlayfieldWithNotes(true));
|
||||||
AddStep("Notes with gravity", () => createPlayfieldWithNotes(true));
|
AddStep("Notes with gravity", () => createPlayfieldWithNotes());
|
||||||
AddStep("Notes with gravity (reversed)", () => createPlayfieldWithNotes(true, true));
|
AddStep("Notes with gravity (reversed)", () => createPlayfieldWithNotes(true));
|
||||||
|
|
||||||
AddStep("Hit explosion", () =>
|
AddStep("Hit explosion", () =>
|
||||||
{
|
{
|
||||||
@ -70,11 +67,6 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
maniaRuleset = rulesets.GetRuleset(3);
|
maniaRuleset = rulesets.GetRuleset(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SpeedAdjustmentContainer createTimingChange(double time, bool gravity) => new ManiaSpeedAdjustmentContainer(new MultiplierControlPoint(time)
|
|
||||||
{
|
|
||||||
TimingPoint = { BeatLength = 1000 }
|
|
||||||
}, gravity ? ScrollingAlgorithm.Gravity : ScrollingAlgorithm.Basic);
|
|
||||||
|
|
||||||
private ManiaPlayfield createPlayfield(int cols, SpecialColumnPosition specialPos, bool inverted = false)
|
private ManiaPlayfield createPlayfield(int cols, SpecialColumnPosition specialPos, bool inverted = false)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
@ -95,7 +87,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
return playfield;
|
return playfield;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPlayfieldWithNotes(bool gravity, bool inverted = false)
|
private void createPlayfieldWithNotes(bool inverted = false)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
@ -114,23 +106,14 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
|
|
||||||
playfield.Inverted.Value = inverted;
|
playfield.Inverted.Value = inverted;
|
||||||
|
|
||||||
if (!gravity)
|
|
||||||
playfield.Columns.ForEach(c => c.Add(createTimingChange(0, false)));
|
|
||||||
|
|
||||||
for (double t = start_time; t <= start_time + duration; t += 100)
|
for (double t = start_time; t <= start_time + duration; t += 100)
|
||||||
{
|
{
|
||||||
if (gravity)
|
|
||||||
playfield.Columns.ElementAt(0).Add(createTimingChange(t, true));
|
|
||||||
|
|
||||||
playfield.Add(new DrawableNote(new Note
|
playfield.Add(new DrawableNote(new Note
|
||||||
{
|
{
|
||||||
StartTime = t,
|
StartTime = t,
|
||||||
Column = 0
|
Column = 0
|
||||||
}, ManiaAction.Key1));
|
}, ManiaAction.Key1));
|
||||||
|
|
||||||
if (gravity)
|
|
||||||
playfield.Columns.ElementAt(3).Add(createTimingChange(t, true));
|
|
||||||
|
|
||||||
playfield.Add(new DrawableNote(new Note
|
playfield.Add(new DrawableNote(new Note
|
||||||
{
|
{
|
||||||
StartTime = t,
|
StartTime = t,
|
||||||
@ -138,9 +121,6 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
}, ManiaAction.Key4));
|
}, ManiaAction.Key4));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gravity)
|
|
||||||
playfield.Columns.ElementAt(1).Add(createTimingChange(start_time, true));
|
|
||||||
|
|
||||||
playfield.Add(new DrawableHoldNote(new HoldNote
|
playfield.Add(new DrawableHoldNote(new HoldNote
|
||||||
{
|
{
|
||||||
StartTime = start_time,
|
StartTime = start_time,
|
||||||
@ -148,9 +128,6 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
Column = 1
|
Column = 1
|
||||||
}, ManiaAction.Key2));
|
}, ManiaAction.Key2));
|
||||||
|
|
||||||
if (gravity)
|
|
||||||
playfield.Columns.ElementAt(2).Add(createTimingChange(start_time, true));
|
|
||||||
|
|
||||||
playfield.Add(new DrawableHoldNote(new HoldNote
|
playfield.Add(new DrawableHoldNote(new HoldNote
|
||||||
{
|
{
|
||||||
StartTime = start_time,
|
StartTime = start_time,
|
||||||
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints
|
public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints
|
||||||
{
|
{
|
||||||
public TestCasePerformancePoints()
|
public TestCasePerformancePoints()
|
||||||
: base(new ManiaRuleset(new RulesetInfo()))
|
: base(new ManiaRuleset())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using osu.Game.Rulesets.Timing;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Timing
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A <see cref="ScrollingContainer"/> that emulates a form of gravity where hit objects speed up over time.
|
|
||||||
/// </summary>
|
|
||||||
internal class GravityScrollingContainer : ScrollingContainer
|
|
||||||
{
|
|
||||||
private readonly MultiplierControlPoint controlPoint;
|
|
||||||
|
|
||||||
public GravityScrollingContainer(MultiplierControlPoint controlPoint)
|
|
||||||
{
|
|
||||||
this.controlPoint = controlPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateAfterChildren()
|
|
||||||
{
|
|
||||||
base.UpdateAfterChildren();
|
|
||||||
|
|
||||||
// The gravity-adjusted start position
|
|
||||||
float startPos = (float)computeGravityTime(controlPoint.StartTime);
|
|
||||||
// The gravity-adjusted end position
|
|
||||||
float endPos = (float)computeGravityTime(controlPoint.StartTime + RelativeChildSize.Y);
|
|
||||||
|
|
||||||
Y = startPos;
|
|
||||||
Height = endPos - startPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Applies gravity to a time value based on the current time.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="time">The time value gravity should be applied to.</param>
|
|
||||||
/// <returns>The time after gravity is applied to <paramref name="time"/>.</returns>
|
|
||||||
private double computeGravityTime(double time)
|
|
||||||
{
|
|
||||||
double relativeTime = relativeTimeAt(time);
|
|
||||||
|
|
||||||
// The sign of the relative time, this is used to apply backwards acceleration leading into startTime
|
|
||||||
double sign = relativeTime < 0 ? -1 : 1;
|
|
||||||
|
|
||||||
return VisibleTimeRange - acceleration * relativeTime * relativeTime * sign;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The acceleration due to "gravity" of the content of this container.
|
|
||||||
/// </summary>
|
|
||||||
private double acceleration => 1 / VisibleTimeRange;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Computes the current time relative to <paramref name="time"/>, accounting for <see cref="ScrollingContainer.VisibleTimeRange"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="time">The non-offset time.</param>
|
|
||||||
/// <returns>The current time relative to <paramref name="time"/> - <see cref="ScrollingContainer.VisibleTimeRange"/>. </returns>
|
|
||||||
private double relativeTimeAt(double time) => Time.Current - time + VisibleTimeRange;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using osu.Game.Rulesets.Timing;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Timing
|
|
||||||
{
|
|
||||||
public class ManiaSpeedAdjustmentContainer : SpeedAdjustmentContainer
|
|
||||||
{
|
|
||||||
private readonly ScrollingAlgorithm scrollingAlgorithm;
|
|
||||||
|
|
||||||
public ManiaSpeedAdjustmentContainer(MultiplierControlPoint timingSection, ScrollingAlgorithm scrollingAlgorithm)
|
|
||||||
: base(timingSection)
|
|
||||||
{
|
|
||||||
this.scrollingAlgorithm = scrollingAlgorithm;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override ScrollingContainer CreateScrollingContainer()
|
|
||||||
{
|
|
||||||
switch (scrollingAlgorithm)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
return base.CreateScrollingContainer();
|
|
||||||
case ScrollingAlgorithm.Gravity:
|
|
||||||
return new GravityScrollingContainer(ControlPoint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Timing
|
|
||||||
{
|
|
||||||
public enum ScrollingAlgorithm
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Basic scrolling algorithm based on the timing section time. This is the default algorithm.
|
|
||||||
/// </summary>
|
|
||||||
Basic,
|
|
||||||
/// <summary>
|
|
||||||
/// Emulating a form of gravity where hit objects speed up over time.
|
|
||||||
/// </summary>
|
|
||||||
Gravity
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,8 +12,8 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
private const float opacity_pressed = 0.25f;
|
private const float opacity_pressed = 0.25f;
|
||||||
|
|
||||||
public Column()
|
public Column()
|
||||||
: base(Axes.Y)
|
: base(ScrollingDirection.Up)
|
||||||
{
|
{
|
||||||
Width = column_width;
|
Width = column_width;
|
||||||
|
|
||||||
@ -204,12 +204,13 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
public override void Add(DrawableHitObject hitObject)
|
public override void Add(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
hitObject.Depth = (float)hitObject.HitObject.StartTime;
|
hitObject.Depth = (float)hitObject.HitObject.StartTime;
|
||||||
|
|
||||||
hitObject.AccentColour = AccentColour;
|
hitObject.AccentColour = AccentColour;
|
||||||
|
hitObject.OnJudgement += onJudgement;
|
||||||
|
|
||||||
HitObjects.Add(hitObject);
|
HitObjects.Add(hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
||||||
{
|
{
|
||||||
if (!judgement.IsHit)
|
if (!judgement.IsHit)
|
||||||
return;
|
return;
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -17,6 +16,7 @@ using osu.Game.Rulesets.Objects.Drawables;
|
|||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
private readonly int columnCount;
|
private readonly int columnCount;
|
||||||
|
|
||||||
public ManiaPlayfield(int columnCount)
|
public ManiaPlayfield(int columnCount)
|
||||||
: base(Axes.Y)
|
: base(ScrollingDirection.Up)
|
||||||
{
|
{
|
||||||
this.columnCount = columnCount;
|
this.columnCount = columnCount;
|
||||||
|
|
||||||
@ -192,11 +192,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
||||||
{
|
{
|
||||||
var maniaObject = (ManiaHitObject)judgedObject.HitObject;
|
|
||||||
columns[maniaObject.Column].OnJudgement(judgedObject, judgement);
|
|
||||||
|
|
||||||
judgements.Clear();
|
judgements.Clear();
|
||||||
judgements.Add(new DrawableManiaJudgement(judgement)
|
judgements.Add(new DrawableManiaJudgement(judgement)
|
||||||
{
|
{
|
||||||
@ -224,7 +221,11 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Add(DrawableHitObject h) => Columns.ElementAt(((ManiaHitObject)h.HitObject).Column).Add(h);
|
public override void Add(DrawableHitObject h)
|
||||||
|
{
|
||||||
|
h.OnJudgement += OnJudgement;
|
||||||
|
Columns.ElementAt(((ManiaHitObject)h.HitObject).Column).Add(h);
|
||||||
|
}
|
||||||
|
|
||||||
public void Add(DrawableBarLine barline) => HitObjects.Add(barline);
|
public void Add(DrawableBarLine barline) => HitObjects.Add(barline);
|
||||||
|
|
||||||
|
@ -16,13 +16,12 @@ using osu.Game.Rulesets.Mania.Objects;
|
|||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Mania.Replays;
|
using osu.Game.Rulesets.Mania.Replays;
|
||||||
using osu.Game.Rulesets.Mania.Scoring;
|
using osu.Game.Rulesets.Mania.Scoring;
|
||||||
using osu.Game.Rulesets.Mania.Timing;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Timing;
|
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
@ -98,8 +97,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(1, 0.8f);
|
protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(1, 0.8f);
|
||||||
|
|
||||||
protected override SpeedAdjustmentContainer CreateSpeedAdjustmentContainer(MultiplierControlPoint controlPoint) => new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Basic);
|
|
||||||
|
|
||||||
protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay, this);
|
protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,30 @@
|
|||||||
<Compile Include="Judgements\HoldNoteTickJudgement.cs" />
|
<Compile Include="Judgements\HoldNoteTickJudgement.cs" />
|
||||||
<Compile Include="Judgements\ManiaJudgement.cs" />
|
<Compile Include="Judgements\ManiaJudgement.cs" />
|
||||||
<Compile Include="ManiaDifficultyCalculator.cs" />
|
<Compile Include="ManiaDifficultyCalculator.cs" />
|
||||||
<Compile Include="Mods\IGenerateSpeedAdjustments.cs" />
|
<Compile Include="Mods\ManiaKeyMod.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModAutoplay.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModDaycore.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModDoubleTime.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModEasy.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModFadeIn.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModFlashlight.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModHalfTime.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModHardRock.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModHidden.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKey1.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKey2.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKey3.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKey4.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKey5.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKey6.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKey7.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKey8.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKey9.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModKeyCoop.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModNightcore.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModPerfect.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModRandom.cs" />
|
||||||
|
<Compile Include="Mods\ManiaModSuddenDeath.cs" />
|
||||||
<Compile Include="Objects\Drawables\DrawableBarLine.cs" />
|
<Compile Include="Objects\Drawables\DrawableBarLine.cs" />
|
||||||
<Compile Include="Objects\Drawables\DrawableHoldNote.cs" />
|
<Compile Include="Objects\Drawables\DrawableHoldNote.cs" />
|
||||||
<Compile Include="Objects\Drawables\DrawableHoldNoteTick.cs" />
|
<Compile Include="Objects\Drawables\DrawableHoldNoteTick.cs" />
|
||||||
@ -90,18 +113,14 @@
|
|||||||
<Compile Include="Tests\TestCaseManiaHitObjects.cs" />
|
<Compile Include="Tests\TestCaseManiaHitObjects.cs" />
|
||||||
<Compile Include="Tests\TestCaseManiaPlayfield.cs" />
|
<Compile Include="Tests\TestCaseManiaPlayfield.cs" />
|
||||||
<Compile Include="Tests\TestCasePerformancePoints.cs" />
|
<Compile Include="Tests\TestCasePerformancePoints.cs" />
|
||||||
<Compile Include="Timing\GravityScrollingContainer.cs" />
|
|
||||||
<Compile Include="Timing\ScrollingAlgorithm.cs" />
|
|
||||||
<Compile Include="UI\Column.cs" />
|
<Compile Include="UI\Column.cs" />
|
||||||
<Compile Include="UI\DrawableManiaJudgement.cs" />
|
<Compile Include="UI\DrawableManiaJudgement.cs" />
|
||||||
<Compile Include="UI\HitExplosion.cs" />
|
<Compile Include="UI\HitExplosion.cs" />
|
||||||
<Compile Include="UI\ManiaRulesetContainer.cs" />
|
<Compile Include="UI\ManiaRulesetContainer.cs" />
|
||||||
<Compile Include="UI\ManiaPlayfield.cs" />
|
<Compile Include="UI\ManiaPlayfield.cs" />
|
||||||
<Compile Include="ManiaRuleset.cs" />
|
<Compile Include="ManiaRuleset.cs" />
|
||||||
<Compile Include="Mods\ManiaMod.cs" />
|
<Compile Include="Mods\ManiaModNoFail.cs" />
|
||||||
<Compile Include="Mods\ManiaModGravity.cs" />
|
|
||||||
<Compile Include="UI\SpecialColumnPosition.cs" />
|
<Compile Include="UI\SpecialColumnPosition.cs" />
|
||||||
<Compile Include="Timing\ManiaSpeedAdjustmentContainer.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.config" />
|
<None Include="app.config" />
|
||||||
|
@ -5,7 +5,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Beatmaps
|
namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||||
{
|
{
|
||||||
@ -29,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
|
colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.ComboIndex = comboIndex++;
|
obj.IndexInCurrentCombo = comboIndex++;
|
||||||
obj.ComboColour = beatmap.ComboColors[colourIndex];
|
obj.ComboColour = beatmap.ComboColors[colourIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,7 +36,6 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
private void applyStacking(Beatmap<OsuHitObject> beatmap)
|
private void applyStacking(Beatmap<OsuHitObject> beatmap)
|
||||||
{
|
{
|
||||||
const int stack_distance = 3;
|
const int stack_distance = 3;
|
||||||
float stackThreshold = DrawableOsuHitObject.TIME_PREEMPT * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
|
|
||||||
|
|
||||||
// Reset stacking
|
// Reset stacking
|
||||||
for (int i = 0; i <= beatmap.HitObjects.Count - 1; i++)
|
for (int i = 0; i <= beatmap.HitObjects.Count - 1; i++)
|
||||||
@ -58,6 +56,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
|
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
|
||||||
|
float stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
|
||||||
|
|
||||||
if (objectN.StartTime - endTime > stackThreshold)
|
if (objectN.StartTime - endTime > stackThreshold)
|
||||||
//We are no longer within stacking range of the next object.
|
//We are no longer within stacking range of the next object.
|
||||||
@ -100,6 +99,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
OsuHitObject objectI = beatmap.HitObjects[i];
|
OsuHitObject objectI = beatmap.HitObjects[i];
|
||||||
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
||||||
|
|
||||||
|
float stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
|
||||||
|
|
||||||
/* If this object is a hitcircle, then we enter this "special" case.
|
/* If this object is a hitcircle, then we enter this "special" case.
|
||||||
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
||||||
* Any other case is handled by the "is Slider" code below this.
|
* Any other case is handled by the "is Slider" code below this.
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Graphics.Cursor;
|
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Edit
|
namespace osu.Game.Rulesets.Osu.Edit
|
||||||
{
|
{
|
||||||
public class OsuEditPlayfield : OsuPlayfield
|
public class OsuEditPlayfield : OsuPlayfield
|
||||||
{
|
{
|
||||||
protected override CursorContainer CreateCursor() => null;
|
|
||||||
|
|
||||||
protected override bool ProxyApproachCircles => false;
|
protected override bool ProxyApproachCircles => false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
@ -15,5 +16,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override Playfield CreatePlayfield() => new OsuEditPlayfield();
|
protected override Playfield CreatePlayfield() => new OsuEditPlayfield();
|
||||||
|
|
||||||
|
protected override CursorContainer CreateCursor() => null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,212 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
||||||
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Rulesets.Osu.Replays;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using OpenTK;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
|
||||||
{
|
|
||||||
public class OsuModNoFail : ModNoFail
|
|
||||||
{
|
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModEasy : ModEasy
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects
|
|
||||||
{
|
|
||||||
public override string Description => @"Play with no approach circles and fading notes for a slight score advantage.";
|
|
||||||
public override double ScoreMultiplier => 1.06;
|
|
||||||
|
|
||||||
private const double fade_in_duration_multiplier = 0.4;
|
|
||||||
private const double fade_out_duration_multiplier = 0.3;
|
|
||||||
|
|
||||||
private float preEmpt => DrawableOsuHitObject.TIME_PREEMPT;
|
|
||||||
|
|
||||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
|
||||||
{
|
|
||||||
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
|
||||||
{
|
|
||||||
d.ApplyCustomUpdateState += ApplyHiddenState;
|
|
||||||
d.FadeInDuration = preEmpt * fade_in_duration_multiplier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
|
|
||||||
{
|
|
||||||
if (!(drawable is DrawableOsuHitObject d))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var fadeOutStartTime = d.HitObject.StartTime - preEmpt + d.FadeInDuration;
|
|
||||||
var fadeOutDuration = preEmpt * fade_out_duration_multiplier;
|
|
||||||
|
|
||||||
// new duration from completed fade in to end (before fading out)
|
|
||||||
var longFadeDuration = ((d.HitObject as IHasEndTime)?.EndTime ?? d.HitObject.StartTime) - fadeOutStartTime;
|
|
||||||
|
|
||||||
switch (drawable)
|
|
||||||
{
|
|
||||||
case DrawableHitCircle circle:
|
|
||||||
// we don't want to see the approach circle
|
|
||||||
circle.ApproachCircle.Hide();
|
|
||||||
|
|
||||||
// fade out immediately after fade in.
|
|
||||||
using (drawable.BeginAbsoluteSequence(fadeOutStartTime, true))
|
|
||||||
circle.FadeOut(fadeOutDuration);
|
|
||||||
break;
|
|
||||||
case DrawableSlider slider:
|
|
||||||
using (slider.BeginAbsoluteSequence(fadeOutStartTime, true))
|
|
||||||
{
|
|
||||||
slider.Body.FadeOut(longFadeDuration, Easing.Out);
|
|
||||||
|
|
||||||
// delay a bit less to let the sliderball fade out peacefully instead of having a hard cut
|
|
||||||
using (slider.BeginDelayedSequence(longFadeDuration - fadeOutDuration, true))
|
|
||||||
slider.Ball.FadeOut(fadeOutDuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case DrawableSpinner spinner:
|
|
||||||
// hide elements we don't care about.
|
|
||||||
spinner.Disc.Hide();
|
|
||||||
spinner.Ticks.Hide();
|
|
||||||
spinner.Background.Hide();
|
|
||||||
|
|
||||||
using (spinner.BeginAbsoluteSequence(fadeOutStartTime + longFadeDuration, true))
|
|
||||||
{
|
|
||||||
spinner.FadeOut(fadeOutDuration);
|
|
||||||
|
|
||||||
// speed up the end sequence accordingly
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case ArmedState.Hit:
|
|
||||||
spinner.ScaleTo(spinner.Scale * 1.2f, fadeOutDuration * 2, Easing.Out);
|
|
||||||
break;
|
|
||||||
case ArmedState.Miss:
|
|
||||||
spinner.ScaleTo(spinner.Scale * 0.8f, fadeOutDuration * 2, Easing.In);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
spinner.Expire();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModHardRock : ModHardRock, IApplicableToHitObject<OsuHitObject>
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.06;
|
|
||||||
public override bool Ranked => true;
|
|
||||||
|
|
||||||
public void ApplyToHitObject(OsuHitObject hitObject)
|
|
||||||
{
|
|
||||||
hitObject.Position = new Vector2(hitObject.Position.X, OsuPlayfield.BASE_SIZE.Y - hitObject.Y);
|
|
||||||
|
|
||||||
var slider = hitObject as Slider;
|
|
||||||
if (slider == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var newControlPoints = new List<Vector2>();
|
|
||||||
slider.ControlPoints.ForEach(c => newControlPoints.Add(new Vector2(c.X, OsuPlayfield.BASE_SIZE.Y - c.Y)));
|
|
||||||
|
|
||||||
slider.ControlPoints = newControlPoints;
|
|
||||||
slider.Curve?.Calculate(); // Recalculate the slider curve
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModSuddenDeath : ModSuddenDeath
|
|
||||||
{
|
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModDaycore : ModDaycore
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModDoubleTime : ModDoubleTime
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.12;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModRelax : ModRelax
|
|
||||||
{
|
|
||||||
public override string Description => "You don't need to click.\nGive your clicking/tapping finger a break from the heat of things.";
|
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModHalfTime : ModHalfTime
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModNightcore : ModNightcore
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.12;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModFlashlight : ModFlashlight
|
|
||||||
{
|
|
||||||
public override double ScoreMultiplier => 1.12;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModPerfect : ModPerfect
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModSpunOut : Mod
|
|
||||||
{
|
|
||||||
public override string Name => "Spun Out";
|
|
||||||
public override string ShortenedName => "SO";
|
|
||||||
public override FontAwesome Icon => FontAwesome.fa_osu_mod_spunout;
|
|
||||||
public override string Description => @"Spinners will be automatically completed";
|
|
||||||
public override double ScoreMultiplier => 0.9;
|
|
||||||
public override bool Ranked => true;
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModAutopilot : Mod
|
|
||||||
{
|
|
||||||
public override string Name => "Autopilot";
|
|
||||||
public override string ShortenedName => "AP";
|
|
||||||
public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot;
|
|
||||||
public override string Description => @"Automatic cursor movement - just follow the rhythm.";
|
|
||||||
public override double ScoreMultiplier => 0;
|
|
||||||
public override bool Ranked => false;
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModAutoplay : ModAutoplay<OsuHitObject>
|
|
||||||
{
|
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModSpunOut) }).ToArray();
|
|
||||||
|
|
||||||
protected override Score CreateReplayScore(Beatmap<OsuHitObject> beatmap) => new Score
|
|
||||||
{
|
|
||||||
Replay = new OsuAutoGenerator(beatmap).Generate()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OsuModTarget : Mod
|
|
||||||
{
|
|
||||||
public override string Name => "Target";
|
|
||||||
public override string ShortenedName => "TP";
|
|
||||||
public override FontAwesome Icon => FontAwesome.fa_osu_mod_target;
|
|
||||||
public override string Description => @"";
|
|
||||||
public override double ScoreMultiplier => 1;
|
|
||||||
}
|
|
||||||
}
|
|
20
osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs
Normal file
20
osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModAutopilot : Mod
|
||||||
|
{
|
||||||
|
public override string Name => "Autopilot";
|
||||||
|
public override string ShortenedName => "AP";
|
||||||
|
public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot;
|
||||||
|
public override string Description => @"Automatic cursor movement - just follow the rhythm.";
|
||||||
|
public override double ScoreMultiplier => 0;
|
||||||
|
public override bool Ranked => false;
|
||||||
|
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) };
|
||||||
|
}
|
||||||
|
}
|
26
osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs
Normal file
26
osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.Replays;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModAutoplay : ModAutoplay<OsuHitObject>
|
||||||
|
{
|
||||||
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModSpunOut) }).ToArray();
|
||||||
|
|
||||||
|
protected override Score CreateReplayScore(Beatmap<OsuHitObject> beatmap)
|
||||||
|
{
|
||||||
|
return new Score
|
||||||
|
{
|
||||||
|
Replay = new OsuAutoGenerator(beatmap).Generate()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs
Normal file
12
osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModDaycore : ModDaycore
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 0.5;
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs
Normal file
12
osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModDoubleTime : ModDoubleTime
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.12;
|
||||||
|
}
|
||||||
|
}
|
11
osu.Game.Rulesets.Osu/Mods/OsuModEasy.cs
Normal file
11
osu.Game.Rulesets.Osu/Mods/OsuModEasy.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModEasy : ModEasy
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs
Normal file
12
osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModFlashlight : ModFlashlight
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 1.12;
|
||||||
|
}
|
||||||
|
}
|
12
osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs
Normal file
12
osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModHalfTime : ModHalfTime
|
||||||
|
{
|
||||||
|
public override double ScoreMultiplier => 0.5;
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user