mirror of
https://github.com/ppy/osu.git
synced 2025-01-24 14:43:22 +08:00
Merge pull request #2051 from smoogipoo/update-branch
Update netstandard with the latest master
This commit is contained in:
commit
d99f686ed6
2
LICENCE
2
LICENCE
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 15fd489d2b4dc1d71a6b98b3001c84f1e60c7c10
|
Subproject commit 86079714a5f5c2678c4cc91df6c0257f33c43bcf
|
@ -1 +1 @@
|
|||||||
Subproject commit 4cc3e92d5576c706060e3d1589bd2a81cf20bfdb
|
Subproject commit 883ff04e79a76f5eb1f89c4f59bd7476a803b42b
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!--
|
<!--
|
||||||
Copyright (c) 2007-2017 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
|
||||||
-->
|
-->
|
||||||
<configuration>
|
<configuration>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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 Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -13,4 +13,4 @@ namespace osu.Desktop.Deploy
|
|||||||
[JsonProperty(@"name")]
|
[JsonProperty(@"name")]
|
||||||
public string Name;
|
public string Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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 Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -25,4 +25,4 @@ namespace osu.Desktop.Deploy
|
|||||||
[JsonProperty(@"upload_url")]
|
[JsonProperty(@"upload_url")]
|
||||||
public string UploadUrl;
|
public string UploadUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
@ -43,7 +43,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;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Platform;
|
using osu.Framework.Platform;
|
||||||
@ -27,4 +27,4 @@ namespace osu.Desktop
|
|||||||
host.Window.CursorState |= CursorState.Hidden;
|
host.Window.CursorState |= CursorState.Hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Diagnostics;
|
using System.Diagnostics;
|
||||||
@ -37,7 +37,8 @@ namespace osu.Desktop.Overlays
|
|||||||
private OsuConfigManager config;
|
private OsuConfigManager config;
|
||||||
private OsuGameBase game;
|
private OsuGameBase game;
|
||||||
|
|
||||||
public override bool HandleInput => false;
|
public override bool HandleKeyboardInput => false;
|
||||||
|
public override bool HandleMouseInput => false;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config)
|
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
@ -46,7 +46,6 @@ namespace osu.Desktop
|
|||||||
host.Run(new OsuGameDesktop(args));
|
host.Run(new OsuGameDesktop(args));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
<description>click the circles. to the beat.</description>
|
<description>click the circles. to the beat.</description>
|
||||||
<summary>click the circles.</summary>
|
<summary>click the circles.</summary>
|
||||||
<releaseNotes>testing</releaseNotes>
|
<releaseNotes>testing</releaseNotes>
|
||||||
<copyright>Copyright ppy Pty Ltd 2007-2017</copyright>
|
<copyright>Copyright ppy Pty Ltd 2007-2018</copyright>
|
||||||
<language>en-AU</language>
|
<language>en-AU</language>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="*.exe" target="lib\net45\" exclude="**vshost**"/>
|
<file src="*.exe" target="lib\net45\" exclude="**vshost**"/>
|
||||||
<file src="*.dll" target="lib\net45\"/>
|
<file src="*.dll" target="lib\net45\"/>
|
||||||
<file src="*.config" target="lib\net45\"/>
|
<file src="*.config" target="lib\net45\"/>
|
||||||
<file src="x86\*.dll" target="lib\net45\x86\"/>
|
<file src="x86\*.dll" target="lib\net45\x86\"/>
|
||||||
<file src="x64\*.dll" target="lib\net45\x64\"/>
|
<file src="x64\*.dll" target="lib\net45\x64\"/>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -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,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
@ -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;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.ComponentModel;
|
using System.ComponentModel;
|
||||||
@ -22,6 +22,6 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
[Description("Move right")]
|
[Description("Move right")]
|
||||||
MoveRight,
|
MoveRight,
|
||||||
[Description("Engage dash")]
|
[Description("Engage dash")]
|
||||||
Dash
|
Dash,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -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,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,28 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
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 (timeOffset > 0)
|
if (CheckPosition == null) return;
|
||||||
AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss });
|
|
||||||
|
if (timeOffset >= 0)
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -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-2017 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-2017 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,28 @@ 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 bool ProvidesJudgement => false;
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
@ -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)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects
|
namespace osu.Game.Rulesets.Catch.Objects
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects
|
namespace osu.Game.Rulesets.Catch.Objects
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
@ -21,9 +21,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float base_scoring_distance = 100;
|
private const float base_scoring_distance = 100;
|
||||||
|
|
||||||
public readonly SliderCurve Curve = new SliderCurve();
|
public int RepeatCount { get; set; }
|
||||||
|
|
||||||
public int RepeatCount { get; set; } = 1;
|
|
||||||
|
|
||||||
public double Velocity;
|
public double Velocity;
|
||||||
public double TickDistance;
|
public double TickDistance;
|
||||||
@ -55,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
|
|
||||||
var length = Curve.Distance;
|
var length = Curve.Distance;
|
||||||
var tickDistance = Math.Min(TickDistance, length);
|
var tickDistance = Math.Min(TickDistance, length);
|
||||||
var repeatDuration = length / Velocity;
|
var spanDuration = length / Velocity;
|
||||||
|
|
||||||
var minDistanceFromEnd = Velocity * 0.01;
|
var minDistanceFromEnd = Velocity * 0.01;
|
||||||
|
|
||||||
@ -67,10 +65,10 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
X = X
|
X = X
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var repeat = 0; repeat < RepeatCount; repeat++)
|
for (var span = 0; span < this.SpanCount(); span++)
|
||||||
{
|
{
|
||||||
var repeatStartTime = StartTime + repeat * repeatDuration;
|
var spanStartTime = StartTime + span * spanDuration;
|
||||||
var reversed = repeat % 2 == 1;
|
var reversed = span % 2 == 1;
|
||||||
|
|
||||||
for (var d = tickDistance; d <= length; d += tickDistance)
|
for (var d = tickDistance; d <= length; d += tickDistance)
|
||||||
{
|
{
|
||||||
@ -80,7 +78,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
var timeProgress = d / length;
|
var timeProgress = d / length;
|
||||||
var distanceProgress = reversed ? 1 - timeProgress : timeProgress;
|
var distanceProgress = reversed ? 1 - timeProgress : timeProgress;
|
||||||
|
|
||||||
var lastTickTime = repeatStartTime + timeProgress * repeatDuration;
|
var lastTickTime = spanStartTime + timeProgress * spanDuration;
|
||||||
AddNested(new Droplet
|
AddNested(new Droplet
|
||||||
{
|
{
|
||||||
StartTime = lastTickTime,
|
StartTime = lastTickTime,
|
||||||
@ -95,17 +93,17 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
double tinyTickInterval = tickDistance / length * repeatDuration;
|
double tinyTickInterval = tickDistance / length * spanDuration;
|
||||||
while (tinyTickInterval > 100)
|
while (tinyTickInterval > 100)
|
||||||
tinyTickInterval /= 2;
|
tinyTickInterval /= 2;
|
||||||
|
|
||||||
for (double t = 0; t < repeatDuration; t += tinyTickInterval)
|
for (double t = 0; t < spanDuration; t += tinyTickInterval)
|
||||||
{
|
{
|
||||||
double progress = reversed ? 1 - t / repeatDuration : t / repeatDuration;
|
double progress = reversed ? 1 - t / spanDuration : t / spanDuration;
|
||||||
|
|
||||||
AddNested(new TinyDroplet
|
AddNested(new TinyDroplet
|
||||||
{
|
{
|
||||||
StartTime = repeatStartTime + t,
|
StartTime = spanStartTime + t,
|
||||||
ComboColour = ComboColour,
|
ComboColour = ComboColour,
|
||||||
X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH,
|
X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH,
|
||||||
Samples = new List<SampleInfo>(Samples.Select(s => new SampleInfo
|
Samples = new List<SampleInfo>(Samples.Select(s => new SampleInfo
|
||||||
@ -121,17 +119,15 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
{
|
{
|
||||||
Samples = Samples,
|
Samples = Samples,
|
||||||
ComboColour = ComboColour,
|
ComboColour = ComboColour,
|
||||||
StartTime = repeatStartTime + repeatDuration,
|
StartTime = spanStartTime + spanDuration,
|
||||||
X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
|
X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double EndTime => StartTime + this.SpanCount() * Curve.Distance / Velocity;
|
||||||
|
|
||||||
public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity;
|
public float EndX => Curve.PositionAt(this.ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH;
|
||||||
|
|
||||||
public float EndX => Curve.PositionAt(ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH;
|
|
||||||
|
|
||||||
public double Duration => EndTime - StartTime;
|
public double Duration => EndTime - StartTime;
|
||||||
|
|
||||||
@ -141,6 +137,8 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
set { Curve.Distance = value; }
|
set { Curve.Distance = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SliderCurve Curve { get; } = new SliderCurve();
|
||||||
|
|
||||||
public List<Vector2> ControlPoints
|
public List<Vector2> ControlPoints
|
||||||
{
|
{
|
||||||
get { return Curve.ControlPoints; }
|
get { return Curve.ControlPoints; }
|
||||||
@ -154,17 +152,5 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
get { return Curve.CurveType; }
|
get { return Curve.CurveType; }
|
||||||
set { Curve.CurveType = value; }
|
set { Curve.CurveType = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress));
|
|
||||||
|
|
||||||
public double ProgressAt(double progress)
|
|
||||||
{
|
|
||||||
double p = progress * RepeatCount % 1;
|
|
||||||
if (RepeatAt(progress) % 2 == 1)
|
|
||||||
p = 1 - p;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int RepeatAt(double progress) => (int)(progress * RepeatCount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects
|
namespace osu.Game.Rulesets.Catch.Objects
|
||||||
|
120
osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs
Normal file
120
osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
// 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.MathUtils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
|
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: add support for HT DT
|
||||||
|
const double dash_speed = CatcherArea.Catcher.BASE_SPEED;
|
||||||
|
const double movement_speed = dash_speed / 2;
|
||||||
|
float lastPosition = 0.5f;
|
||||||
|
double lastTime = 0;
|
||||||
|
|
||||||
|
// 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, lastPosition));
|
||||||
|
|
||||||
|
void moveToNext(CatchHitObject h)
|
||||||
|
{
|
||||||
|
float positionChange = Math.Abs(lastPosition - h.X);
|
||||||
|
double timeAvailable = h.StartTime - lastTime;
|
||||||
|
|
||||||
|
//So we can either make it there without a dash or not.
|
||||||
|
double speedRequired = positionChange / timeAvailable;
|
||||||
|
|
||||||
|
bool dashRequired = speedRequired > movement_speed && h.StartTime != 0;
|
||||||
|
|
||||||
|
// todo: get correct catcher size, based on difficulty CS.
|
||||||
|
const float catcher_width_half = CatcherArea.CATCHER_SIZE / CatchPlayfield.BASE_WIDTH * 0.3f * 0.5f;
|
||||||
|
|
||||||
|
if (lastPosition - catcher_width_half < h.X && lastPosition + catcher_width_half > h.X)
|
||||||
|
{
|
||||||
|
//we are already in the correct range.
|
||||||
|
lastTime = h.StartTime;
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, lastPosition));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h is BananaShower.Banana)
|
||||||
|
{
|
||||||
|
// auto bananas unrealistically warp to catch 100% combo.
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
|
||||||
|
}
|
||||||
|
else if (h.HyperDash)
|
||||||
|
{
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeAvailable, lastPosition, ReplayButtonState.Right1));
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
|
||||||
|
}
|
||||||
|
else if (dashRequired)
|
||||||
|
{
|
||||||
|
//we do a movement in two parts - the dash part then the normal part...
|
||||||
|
double timeAtNormalSpeed = positionChange / movement_speed;
|
||||||
|
double timeWeNeedToSave = timeAtNormalSpeed - timeAvailable;
|
||||||
|
double timeAtDashSpeed = timeWeNeedToSave / 2;
|
||||||
|
|
||||||
|
float midPosition = (float)Interpolation.Lerp(lastPosition, h.X, (float)timeAtDashSpeed / timeAvailable);
|
||||||
|
|
||||||
|
//dash movement
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeAvailable + 1, lastPosition, ReplayButtonState.Left1));
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeAvailable + timeAtDashSpeed, midPosition));
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double timeBefore = positionChange / movement_speed;
|
||||||
|
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeBefore, lastPosition, ReplayButtonState.Right1));
|
||||||
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTime = h.StartTime;
|
||||||
|
lastPosition = h.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var obj in Beatmap.HitObjects)
|
||||||
|
{
|
||||||
|
switch (obj)
|
||||||
|
{
|
||||||
|
case Fruit _:
|
||||||
|
moveToNext(obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var nestedObj in obj.NestedHitObjects.Cast<CatchHitObject>())
|
||||||
|
{
|
||||||
|
switch (nestedObj)
|
||||||
|
{
|
||||||
|
case BananaShower.Banana _:
|
||||||
|
case TinyDroplet _:
|
||||||
|
case Droplet _:
|
||||||
|
moveToNext(nestedObj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Replay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
// 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()
|
||||||
|
{
|
||||||
|
if (!Position.HasValue) return new List<InputState>();
|
||||||
|
|
||||||
|
var action = new List<CatchAction>();
|
||||||
|
|
||||||
|
if (CurrentFrame.ButtonState == ReplayButtonState.Left1)
|
||||||
|
action.Add(CatchAction.Dash);
|
||||||
|
|
||||||
|
if (Position.Value.X > CurrentFrame.Position.X)
|
||||||
|
action.Add(CatchAction.MoveRight);
|
||||||
|
else if (Position.Value.X < CurrentFrame.Position.X)
|
||||||
|
action.Add(CatchAction.MoveLeft);
|
||||||
|
|
||||||
|
return new List<InputState>
|
||||||
|
{
|
||||||
|
new CatchReplayState
|
||||||
|
{
|
||||||
|
PressedActions = action,
|
||||||
|
CatcherX = Position.Value.X
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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, ReplayButtonState button = ReplayButtonState.None)
|
||||||
|
: base(time, x ?? -1, null, button)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Linq;
|
using System.Linq;
|
||||||
@ -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,21 @@ 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 });
|
foreach (var _ in stream.NestedHitObjects.Cast<CatchHitObject>())
|
||||||
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
foreach (var unused in stream.NestedHitObjects.OfType<CatchHitObject>())
|
break;
|
||||||
|
case BananaShower shower:
|
||||||
|
foreach (var _ in shower.NestedHitObjects.Cast<CatchHitObject>())
|
||||||
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||||
|
break;
|
||||||
continue;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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 NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -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())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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 NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -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())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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 NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -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())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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 NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -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-2017 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,33 +22,35 @@ 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>
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
explodingFruitContainer = new Container
|
explodingFruitContainer = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
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,
|
||||||
}
|
},
|
||||||
};
|
content = new Container<Drawable>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Input;
|
using osu.Framework.Input;
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
@ -12,6 +12,9 @@ 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;
|
||||||
@ -24,6 +27,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
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,58 @@ 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void UpdateAfterChildren()
|
||||||
|
{
|
||||||
|
base.UpdateAfterChildren();
|
||||||
|
|
||||||
|
var state = GetContainingInputManager().CurrentState as CatchFramedReplayInputHandler.CatchReplayState;
|
||||||
|
|
||||||
|
if (state?.CatcherX != null)
|
||||||
|
MovableCatcher.X = state.CatcherX.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 +128,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 +211,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 +237,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 +356,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();
|
||||||
|
|
||||||
|
33
osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
Normal file
33
osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// 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.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||||
|
{
|
||||||
|
public class ManiaBeatmap : Beatmap<ManiaHitObject>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The definitions for each stage in a <see cref="ManiaPlayfield"/>.
|
||||||
|
/// </summary>
|
||||||
|
public List<StageDefinition> Stages = new List<StageDefinition>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total number of columns represented by all stages in this <see cref="ManiaBeatmap"/>.
|
||||||
|
/// </summary>
|
||||||
|
public int TotalColumns => Stages.Sum(g => g.Columns);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="ManiaBeatmap"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="defaultStage">The initial stages.</param>
|
||||||
|
public ManiaBeatmap(StageDefinition defaultStage)
|
||||||
|
{
|
||||||
|
Stages.Add(defaultStage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -24,25 +25,39 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
|
|
||||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
||||||
|
|
||||||
|
public int TargetColumns;
|
||||||
|
public readonly bool IsForCurrentRuleset;
|
||||||
|
|
||||||
private Pattern lastPattern = new Pattern();
|
private Pattern lastPattern = new Pattern();
|
||||||
private FastRandom random;
|
private FastRandom random;
|
||||||
private Beatmap beatmap;
|
|
||||||
|
|
||||||
private readonly int availableColumns;
|
private ManiaBeatmap beatmap;
|
||||||
private readonly bool isForCurrentRuleset;
|
|
||||||
|
|
||||||
public ManiaBeatmapConverter(bool isForCurrentRuleset, int availableColumns)
|
public ManiaBeatmapConverter(bool isForCurrentRuleset, Beatmap original)
|
||||||
{
|
{
|
||||||
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
|
IsForCurrentRuleset = isForCurrentRuleset;
|
||||||
|
|
||||||
this.isForCurrentRuleset = isForCurrentRuleset;
|
var roundedCircleSize = Math.Round(original.BeatmapInfo.BaseDifficulty.CircleSize);
|
||||||
this.availableColumns = availableColumns;
|
var roundedOverallDifficulty = Math.Round(original.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
||||||
|
|
||||||
|
if (isForCurrentRuleset)
|
||||||
|
TargetColumns = (int)Math.Max(1, roundedCircleSize);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float percentSliderOrSpinner = (float)original.HitObjects.Count(h => h is IHasEndTime) / original.HitObjects.Count;
|
||||||
|
if (percentSliderOrSpinner < 0.2)
|
||||||
|
TargetColumns = 7;
|
||||||
|
else if (percentSliderOrSpinner < 0.3 || roundedCircleSize >= 5)
|
||||||
|
TargetColumns = roundedOverallDifficulty > 5 ? 7 : 6;
|
||||||
|
else if (percentSliderOrSpinner > 0.6)
|
||||||
|
TargetColumns = roundedOverallDifficulty > 4 ? 5 : 4;
|
||||||
|
else
|
||||||
|
TargetColumns = Math.Max(4, Math.Min((int)roundedOverallDifficulty + 1, 7));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Beatmap<ManiaHitObject> ConvertBeatmap(Beatmap original)
|
protected override Beatmap<ManiaHitObject> ConvertBeatmap(Beatmap original)
|
||||||
{
|
{
|
||||||
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);
|
||||||
@ -51,6 +66,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
return base.ConvertBeatmap(original);
|
return base.ConvertBeatmap(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override Beatmap<ManiaHitObject> CreateBeatmap() => beatmap = new ManiaBeatmap(new StageDefinition { Columns = TargetColumns });
|
||||||
|
|
||||||
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, Beatmap beatmap)
|
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, Beatmap beatmap)
|
||||||
{
|
{
|
||||||
var maniaOriginal = original as ManiaHitObject;
|
var maniaOriginal = original as ManiaHitObject;
|
||||||
@ -60,7 +77,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var objects = isForCurrentRuleset ? generateSpecific(original) : generateConverted(original);
|
var objects = IsForCurrentRuleset ? generateSpecific(original) : generateConverted(original);
|
||||||
|
|
||||||
if (objects == null)
|
if (objects == null)
|
||||||
yield break;
|
yield break;
|
||||||
@ -96,7 +113,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
/// <returns>The hit objects generated.</returns>
|
/// <returns>The hit objects generated.</returns>
|
||||||
private IEnumerable<ManiaHitObject> generateSpecific(HitObject original)
|
private IEnumerable<ManiaHitObject> generateSpecific(HitObject original)
|
||||||
{
|
{
|
||||||
var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, availableColumns, lastPattern);
|
var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern);
|
||||||
|
|
||||||
Pattern newPattern = generator.Generate();
|
Pattern newPattern = generator.Generate();
|
||||||
lastPattern = newPattern;
|
lastPattern = newPattern;
|
||||||
@ -120,14 +137,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
Patterns.PatternGenerator conversion = null;
|
Patterns.PatternGenerator conversion = null;
|
||||||
|
|
||||||
if (distanceData != null)
|
if (distanceData != null)
|
||||||
conversion = new DistanceObjectPatternGenerator(random, original, beatmap, availableColumns, lastPattern);
|
conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern);
|
||||||
else if (endTimeData != null)
|
else if (endTimeData != null)
|
||||||
conversion = new EndTimeObjectPatternGenerator(random, original, beatmap, availableColumns);
|
conversion = new EndTimeObjectPatternGenerator(random, original, beatmap);
|
||||||
else if (positionData != null)
|
else if (positionData != null)
|
||||||
{
|
{
|
||||||
computeDensity(original.StartTime);
|
computeDensity(original.StartTime);
|
||||||
|
|
||||||
conversion = new HitObjectPatternGenerator(random, original, beatmap, availableColumns, lastPattern, lastTime, lastPosition, density, lastStair);
|
conversion = new HitObjectPatternGenerator(random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair);
|
||||||
|
|
||||||
recordNote(original.StartTime, positionData.Position);
|
recordNote(original.StartTime, positionData.Position);
|
||||||
}
|
}
|
||||||
@ -149,8 +166,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
|
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
|
||||||
{
|
{
|
||||||
public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||||
: base(random, hitObject, beatmap, availableColumns, previousPattern)
|
: base(random, hitObject, beatmap, previousPattern)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +216,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
if (curveData == null)
|
if (curveData == null)
|
||||||
return HitObject.Samples;
|
return HitObject.Samples;
|
||||||
|
|
||||||
double segmentTime = (curveData.EndTime - HitObject.StartTime) / curveData.RepeatCount;
|
double segmentTime = (curveData.EndTime - HitObject.StartTime) / curveData.SpanCount();
|
||||||
|
|
||||||
int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime);
|
int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime);
|
||||||
return curveData.RepeatSamples[index];
|
return curveData.RepeatSamples[index];
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
using osu.Game.Rulesets.Mania.MathUtils;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -26,12 +25,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
private readonly double endTime;
|
private readonly double endTime;
|
||||||
private readonly double segmentDuration;
|
private readonly double segmentDuration;
|
||||||
private readonly int repeatCount;
|
private readonly int spanCount;
|
||||||
|
|
||||||
private PatternType convertType;
|
private PatternType convertType;
|
||||||
|
|
||||||
public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||||
: base(random, hitObject, beatmap, availableColumns, previousPattern)
|
: base(random, hitObject, beatmap, previousPattern)
|
||||||
{
|
{
|
||||||
convertType = PatternType.None;
|
convertType = PatternType.None;
|
||||||
if (Beatmap.ControlPointInfo.EffectPointAt(hitObject.StartTime).KiaiMode)
|
if (Beatmap.ControlPointInfo.EffectPointAt(hitObject.StartTime).KiaiMode)
|
||||||
@ -40,25 +39,25 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
var distanceData = hitObject as IHasDistance;
|
var distanceData = hitObject as IHasDistance;
|
||||||
var repeatsData = hitObject as IHasRepeats;
|
var repeatsData = hitObject as IHasRepeats;
|
||||||
|
|
||||||
repeatCount = repeatsData?.RepeatCount ?? 1;
|
spanCount = repeatsData?.SpanCount() ?? 1;
|
||||||
|
|
||||||
TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime);
|
TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime);
|
||||||
DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(hitObject.StartTime);
|
DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(hitObject.StartTime);
|
||||||
|
|
||||||
// The true distance, accounting for any repeats
|
// The true distance, accounting for any repeats
|
||||||
double distance = (distanceData?.Distance ?? 0) * repeatCount;
|
double distance = (distanceData?.Distance ?? 0) * spanCount;
|
||||||
// The velocity of the osu! hit object - calculated as the velocity of a slider
|
// The velocity of the osu! hit object - calculated as the velocity of a slider
|
||||||
double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / timingPoint.BeatLength;
|
double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / timingPoint.BeatLength;
|
||||||
// The duration of the osu! hit object
|
// The duration of the osu! hit object
|
||||||
double osuDuration = distance / osuVelocity;
|
double osuDuration = distance / osuVelocity;
|
||||||
|
|
||||||
endTime = hitObject.StartTime + osuDuration;
|
endTime = hitObject.StartTime + osuDuration;
|
||||||
segmentDuration = (endTime - HitObject.StartTime) / repeatCount;
|
segmentDuration = (endTime - HitObject.StartTime) / spanCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Pattern Generate()
|
public override Pattern Generate()
|
||||||
{
|
{
|
||||||
if (repeatCount > 1)
|
if (spanCount > 1)
|
||||||
{
|
{
|
||||||
if (segmentDuration <= 90)
|
if (segmentDuration <= 90)
|
||||||
return generateRandomHoldNotes(HitObject.StartTime, 1);
|
return generateRandomHoldNotes(HitObject.StartTime, 1);
|
||||||
@ -66,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if (segmentDuration <= 120)
|
if (segmentDuration <= 120)
|
||||||
{
|
{
|
||||||
convertType |= PatternType.ForceNotStack;
|
convertType |= PatternType.ForceNotStack;
|
||||||
return generateRandomNotes(HitObject.StartTime, repeatCount + 1);
|
return generateRandomNotes(HitObject.StartTime, spanCount + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segmentDuration <= 160)
|
if (segmentDuration <= 160)
|
||||||
@ -79,7 +78,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if (duration >= 4000)
|
if (duration >= 4000)
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0);
|
||||||
|
|
||||||
if (segmentDuration > 400 && repeatCount < AvailableColumns - 1 - RandomStart)
|
if (segmentDuration > 400 && spanCount < TotalColumns - 1 - RandomStart)
|
||||||
return generateTiledHoldNotes(HitObject.StartTime);
|
return generateTiledHoldNotes(HitObject.StartTime);
|
||||||
|
|
||||||
return generateHoldAndNormalNotes(HitObject.StartTime);
|
return generateHoldAndNormalNotes(HitObject.StartTime);
|
||||||
@ -87,7 +86,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (segmentDuration <= 110)
|
if (segmentDuration <= 110)
|
||||||
{
|
{
|
||||||
if (PreviousPattern.ColumnWithObjects < AvailableColumns)
|
if (PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
convertType |= PatternType.ForceNotStack;
|
convertType |= PatternType.ForceNotStack;
|
||||||
else
|
else
|
||||||
convertType &= ~PatternType.ForceNotStack;
|
convertType &= ~PatternType.ForceNotStack;
|
||||||
@ -135,12 +134,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int usableColumns = AvailableColumns - RandomStart - PreviousPattern.ColumnWithObjects;
|
int usableColumns = TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects;
|
||||||
int nextColumn = Random.Next(RandomStart, AvailableColumns);
|
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
|
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn)) //find available column
|
while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn)) //find available column
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
addToPattern(pattern, nextColumn, startTime, endTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
for (int i = 0; i < noteCount - usableColumns; i++)
|
for (int i = 0; i < noteCount - usableColumns; i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn))
|
while (pattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
addToPattern(pattern, nextColumn, startTime, endTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,10 +171,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < AvailableColumns)
|
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
{
|
{
|
||||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
while (PreviousPattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastColumn = nextColumn;
|
int lastColumn = nextColumn;
|
||||||
@ -183,7 +182,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||||
while (nextColumn == lastColumn)
|
while (nextColumn == lastColumn)
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
|
||||||
lastColumn = nextColumn;
|
lastColumn = nextColumn;
|
||||||
startTime += segmentDuration;
|
startTime += segmentDuration;
|
||||||
@ -213,7 +212,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int column = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int column = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
bool increasing = Random.NextDouble() > 0.5;
|
bool increasing = Random.NextDouble() > 0.5;
|
||||||
|
|
||||||
for (int i = 0; i <= repeatCount; i++)
|
for (int i = 0; i <= spanCount; i++)
|
||||||
{
|
{
|
||||||
addToPattern(pattern, column, startTime, startTime);
|
addToPattern(pattern, column, startTime, startTime);
|
||||||
startTime += segmentDuration;
|
startTime += segmentDuration;
|
||||||
@ -221,7 +220,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// Check if we're at the borders of the stage, and invert the pattern if so
|
// Check if we're at the borders of the stage, and invert the pattern if so
|
||||||
if (increasing)
|
if (increasing)
|
||||||
{
|
{
|
||||||
if (column >= AvailableColumns - 1)
|
if (column >= TotalColumns - 1)
|
||||||
{
|
{
|
||||||
increasing = false;
|
increasing = false;
|
||||||
column--;
|
column--;
|
||||||
@ -259,24 +258,24 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
bool legacy = AvailableColumns >= 4 && AvailableColumns <= 8;
|
bool legacy = TotalColumns >= 4 && TotalColumns <= 8;
|
||||||
int interval = Random.Next(1, AvailableColumns - (legacy ? 1 : 0));
|
int interval = Random.Next(1, TotalColumns - (legacy ? 1 : 0));
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
for (int i = 0; i <= repeatCount; i++)
|
for (int i = 0; i <= spanCount; i++)
|
||||||
{
|
{
|
||||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||||
|
|
||||||
nextColumn += interval;
|
nextColumn += interval;
|
||||||
if (nextColumn >= AvailableColumns - RandomStart)
|
if (nextColumn >= TotalColumns - RandomStart)
|
||||||
nextColumn = nextColumn - AvailableColumns - RandomStart + (legacy ? 1 : 0);
|
nextColumn = nextColumn - TotalColumns - RandomStart + (legacy ? 1 : 0);
|
||||||
nextColumn += RandomStart;
|
nextColumn += RandomStart;
|
||||||
|
|
||||||
// If we're in 2K, let's not add many consecutive doubles
|
// If we're in 2K, let's not add many consecutive doubles
|
||||||
if (AvailableColumns > 2)
|
if (TotalColumns > 2)
|
||||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||||
|
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
startTime += segmentDuration;
|
startTime += segmentDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +297,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// □ - □ □
|
// □ - □ □
|
||||||
// ■ - ■ ■
|
// ■ - ■ ■
|
||||||
|
|
||||||
switch (AvailableColumns)
|
switch (TotalColumns)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
p2 = 0;
|
p2 = 0;
|
||||||
@ -322,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);
|
||||||
@ -351,19 +350,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int columnRepeat = Math.Min(repeatCount, AvailableColumns);
|
int columnRepeat = Math.Min(spanCount, TotalColumns);
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < AvailableColumns)
|
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
{
|
{
|
||||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
while (PreviousPattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < columnRepeat; i++)
|
for (int i = 0; i < columnRepeat; i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn))
|
while (pattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
|
||||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
addToPattern(pattern, nextColumn, startTime, endTime);
|
||||||
startTime += segmentDuration;
|
startTime += segmentDuration;
|
||||||
@ -388,10 +387,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < AvailableColumns)
|
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
{
|
{
|
||||||
while (PreviousPattern.ColumnHasObject(holdColumn))
|
while (PreviousPattern.ColumnHasObject(holdColumn))
|
||||||
holdColumn = Random.Next(RandomStart, AvailableColumns);
|
holdColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the hold note
|
// Create the hold note
|
||||||
@ -401,23 +400,23 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if (ConversionDifficulty > 6.5)
|
if (ConversionDifficulty > 6.5)
|
||||||
noteCount = GetRandomNoteCount(0.63, 0);
|
noteCount = GetRandomNoteCount(0.63, 0);
|
||||||
else if (ConversionDifficulty > 4)
|
else if (ConversionDifficulty > 4)
|
||||||
noteCount = GetRandomNoteCount(AvailableColumns < 6 ? 0.12 : 0.45, 0);
|
noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0.12 : 0.45, 0);
|
||||||
else if (ConversionDifficulty > 2.5)
|
else if (ConversionDifficulty > 2.5)
|
||||||
noteCount = GetRandomNoteCount(AvailableColumns < 6 ? 0 : 0.24, 0);
|
noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0 : 0.24, 0);
|
||||||
noteCount = Math.Min(AvailableColumns - 1, noteCount);
|
noteCount = Math.Min(TotalColumns - 1, noteCount);
|
||||||
|
|
||||||
bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);
|
bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);
|
||||||
int nextColumn = Random.Next(RandomStart, AvailableColumns);
|
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
|
||||||
var rowPattern = new Pattern();
|
var rowPattern = new Pattern();
|
||||||
for (int i = 0; i <= repeatCount; i++)
|
for (int i = 0; i <= spanCount; i++)
|
||||||
{
|
{
|
||||||
if (!(ignoreHead && startTime == HitObject.StartTime))
|
if (!(ignoreHead && startTime == HitObject.StartTime))
|
||||||
{
|
{
|
||||||
for (int j = 0; j < noteCount; j++)
|
for (int j = 0; j < noteCount; j++)
|
||||||
{
|
{
|
||||||
while (rowPattern.ColumnHasObject(nextColumn) || nextColumn == holdColumn)
|
while (rowPattern.ColumnHasObject(nextColumn) || nextColumn == holdColumn)
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
addToPattern(rowPattern, nextColumn, startTime, startTime);
|
addToPattern(rowPattern, nextColumn, startTime, startTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,7 +442,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if (curveData == null)
|
if (curveData == null)
|
||||||
return HitObject.Samples;
|
return HitObject.Samples;
|
||||||
|
|
||||||
double segmentTime = (endTime - HitObject.StartTime) / repeatCount;
|
double segmentTime = (endTime - HitObject.StartTime) / spanCount;
|
||||||
|
|
||||||
int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime);
|
int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime);
|
||||||
return curveData.RepeatSamples[index];
|
return curveData.RepeatSamples[index];
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
// Copyright (c) 2007-2017 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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
using osu.Game.Rulesets.Mania.MathUtils;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -16,8 +15,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
private readonly double endTime;
|
private readonly double endTime;
|
||||||
|
|
||||||
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns)
|
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap)
|
||||||
: base(random, hitObject, beatmap, availableColumns, new Pattern())
|
: base(random, hitObject, beatmap, new Pattern())
|
||||||
{
|
{
|
||||||
var endtimeData = HitObject as IHasEndTime;
|
var endtimeData = HitObject as IHasEndTime;
|
||||||
|
|
||||||
@ -30,14 +29,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
bool generateHold = endTime - HitObject.StartTime >= 100;
|
bool generateHold = endTime - HitObject.StartTime >= 100;
|
||||||
|
|
||||||
if (AvailableColumns == 8)
|
if (TotalColumns == 8)
|
||||||
{
|
{
|
||||||
if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000)
|
if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000)
|
||||||
addToPattern(pattern, 0, generateHold);
|
addToPattern(pattern, 0, generateHold);
|
||||||
else
|
else
|
||||||
addToPattern(pattern, getNextRandomColumn(RandomStart), generateHold);
|
addToPattern(pattern, getNextRandomColumn(RandomStart), generateHold);
|
||||||
}
|
}
|
||||||
else if (AvailableColumns > 0)
|
else if (TotalColumns > 0)
|
||||||
addToPattern(pattern, getNextRandomColumn(0), generateHold);
|
addToPattern(pattern, getNextRandomColumn(0), generateHold);
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -50,10 +49,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// <returns>A random column after <paramref name="start"/>.</returns>
|
/// <returns>A random column after <paramref name="start"/>.</returns>
|
||||||
private int getNextRandomColumn(int start)
|
private int getNextRandomColumn(int start)
|
||||||
{
|
{
|
||||||
int nextColumn = Random.Next(start, AvailableColumns);
|
int nextColumn = Random.Next(start, TotalColumns);
|
||||||
|
|
||||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
while (PreviousPattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(start, AvailableColumns);
|
nextColumn = Random.Next(start, TotalColumns);
|
||||||
|
|
||||||
return nextColumn;
|
return nextColumn;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
using osu.Game.Rulesets.Mania.MathUtils;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
@ -20,8 +19,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
private readonly PatternType convertType;
|
private readonly PatternType convertType;
|
||||||
|
|
||||||
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair)
|
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair)
|
||||||
: base(random, hitObject, beatmap, availableColumns, previousPattern)
|
: base(random, hitObject, beatmap, previousPattern)
|
||||||
{
|
{
|
||||||
if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime));
|
if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime));
|
||||||
if (density < 0) throw new ArgumentOutOfRangeException(nameof(density));
|
if (density < 0) throw new ArgumentOutOfRangeException(nameof(density));
|
||||||
@ -88,23 +87,23 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// Generate a new pattern by copying the last hit objects in reverse-column order
|
// Generate a new pattern by copying the last hit objects in reverse-column order
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
for (int i = RandomStart; i < AvailableColumns; i++)
|
for (int i = RandomStart; i < TotalColumns; i++)
|
||||||
if (PreviousPattern.ColumnHasObject(i))
|
if (PreviousPattern.ColumnHasObject(i))
|
||||||
addToPattern(pattern, RandomStart + AvailableColumns - i - 1);
|
addToPattern(pattern, RandomStart + TotalColumns - i - 1);
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1
|
if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1
|
||||||
// If we convert to 7K + 1, let's not overload the special key
|
// If we convert to 7K + 1, let's not overload the special key
|
||||||
&& (AvailableColumns != 8 || lastColumn != 0)
|
&& (TotalColumns != 8 || lastColumn != 0)
|
||||||
// Make sure the last column was not the centre column
|
// Make sure the last column was not the centre column
|
||||||
&& (AvailableColumns % 2 == 0 || lastColumn != AvailableColumns / 2))
|
&& (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2))
|
||||||
{
|
{
|
||||||
// Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object)
|
// Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object)
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int column = RandomStart + AvailableColumns - lastColumn - 1;
|
int column = RandomStart + TotalColumns - lastColumn - 1;
|
||||||
addToPattern(pattern, column);
|
addToPattern(pattern, column);
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -115,7 +114,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// Generate a new pattern by placing on the already filled columns
|
// Generate a new pattern by placing on the already filled columns
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
for (int i = RandomStart; i < AvailableColumns; i++)
|
for (int i = RandomStart; i < TotalColumns; i++)
|
||||||
if (PreviousPattern.ColumnHasObject(i))
|
if (PreviousPattern.ColumnHasObject(i))
|
||||||
addToPattern(pattern, i);
|
addToPattern(pattern, i);
|
||||||
|
|
||||||
@ -128,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int targetColumn = lastColumn + 1;
|
int targetColumn = lastColumn + 1;
|
||||||
if (targetColumn == AvailableColumns)
|
if (targetColumn == TotalColumns)
|
||||||
{
|
{
|
||||||
targetColumn = RandomStart;
|
targetColumn = RandomStart;
|
||||||
StairType = PatternType.ReverseStair;
|
StairType = PatternType.ReverseStair;
|
||||||
@ -146,7 +145,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int targetColumn = lastColumn - 1;
|
int targetColumn = lastColumn - 1;
|
||||||
if (targetColumn == RandomStart - 1)
|
if (targetColumn == RandomStart - 1)
|
||||||
{
|
{
|
||||||
targetColumn = AvailableColumns - 1;
|
targetColumn = TotalColumns - 1;
|
||||||
StairType = PatternType.Stair;
|
StairType = PatternType.Stair;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +205,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
bool allowStacking = (convertType & PatternType.ForceNotStack) == 0;
|
bool allowStacking = (convertType & PatternType.ForceNotStack) == 0;
|
||||||
|
|
||||||
if (!allowStacking)
|
if (!allowStacking)
|
||||||
noteCount = Math.Min(noteCount, AvailableColumns - RandomStart - PreviousPattern.ColumnWithObjects);
|
noteCount = Math.Min(noteCount, TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects);
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
for (int i = 0; i < noteCount; i++)
|
for (int i = 0; i < noteCount; i++)
|
||||||
@ -216,11 +215,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if ((convertType & PatternType.Gathered) > 0)
|
if ((convertType & PatternType.Gathered) > 0)
|
||||||
{
|
{
|
||||||
nextColumn++;
|
nextColumn++;
|
||||||
if (nextColumn == AvailableColumns)
|
if (nextColumn == TotalColumns)
|
||||||
nextColumn = RandomStart;
|
nextColumn = RandomStart;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
addToPattern(pattern, nextColumn);
|
addToPattern(pattern, nextColumn);
|
||||||
@ -268,7 +267,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
bool addToCentre;
|
bool addToCentre;
|
||||||
int noteCount = getRandomNoteCountMirrored(centreProbability, p2, p3, out addToCentre);
|
int noteCount = getRandomNoteCountMirrored(centreProbability, p2, p3, out addToCentre);
|
||||||
|
|
||||||
int columnLimit = (AvailableColumns % 2 == 0 ? AvailableColumns : AvailableColumns - 1) / 2;
|
int columnLimit = (TotalColumns % 2 == 0 ? TotalColumns : TotalColumns - 1) / 2;
|
||||||
int nextColumn = Random.Next(RandomStart, columnLimit);
|
int nextColumn = Random.Next(RandomStart, columnLimit);
|
||||||
for (int i = 0; i < noteCount; i++)
|
for (int i = 0; i < noteCount; i++)
|
||||||
{
|
{
|
||||||
@ -278,11 +277,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// Add normal note
|
// Add normal note
|
||||||
addToPattern(pattern, nextColumn);
|
addToPattern(pattern, nextColumn);
|
||||||
// Add mirrored note
|
// Add mirrored note
|
||||||
addToPattern(pattern, RandomStart + AvailableColumns - nextColumn - 1);
|
addToPattern(pattern, RandomStart + TotalColumns - nextColumn - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addToCentre)
|
if (addToCentre)
|
||||||
addToPattern(pattern, AvailableColumns / 2);
|
addToPattern(pattern, TotalColumns / 2);
|
||||||
|
|
||||||
if (RandomStart > 0 && hasSpecialColumn)
|
if (RandomStart > 0 && hasSpecialColumn)
|
||||||
addToPattern(pattern, 0);
|
addToPattern(pattern, 0);
|
||||||
@ -300,7 +299,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// <returns>The amount of notes to be generated.</returns>
|
/// <returns>The amount of notes to be generated.</returns>
|
||||||
private int getRandomNoteCount(double p2, double p3, double p4, double p5)
|
private int getRandomNoteCount(double p2, double p3, double p4, double p5)
|
||||||
{
|
{
|
||||||
switch (AvailableColumns)
|
switch (TotalColumns)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
p2 = 0;
|
p2 = 0;
|
||||||
@ -348,7 +347,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if ((convertType & PatternType.ForceNotStack) > 0)
|
if ((convertType & PatternType.ForceNotStack) > 0)
|
||||||
return getRandomNoteCount(p2 / 2, p2, (p2 + p3) / 2, p3);
|
return getRandomNoteCount(p2 / 2, p2, (p2 + p3) / 2, p3);
|
||||||
|
|
||||||
switch (AvailableColumns)
|
switch (TotalColumns)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
centreProbability = 0;
|
centreProbability = 0;
|
||||||
@ -379,7 +378,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
double centreVal = Random.NextDouble();
|
double centreVal = Random.NextDouble();
|
||||||
int noteCount = GetRandomNoteCount(p2, p3);
|
int noteCount = GetRandomNoteCount(p2, p3);
|
||||||
|
|
||||||
addToCentre = AvailableColumns % 2 != 0 && noteCount != 3 && centreVal > 1 - centreProbability;
|
addToCentre = TotalColumns % 2 != 0 && noteCount != 3 && centreVal > 1 - centreProbability;
|
||||||
return noteCount;
|
return noteCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
@ -25,16 +25,15 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly FastRandom Random;
|
protected readonly FastRandom Random;
|
||||||
|
|
||||||
protected PatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||||
: base(hitObject, beatmap, availableColumns, previousPattern)
|
: base(hitObject, beatmap, previousPattern)
|
||||||
{
|
{
|
||||||
if (random == null) throw new ArgumentNullException(nameof(random));
|
if (random == null) throw new ArgumentNullException(nameof(random));
|
||||||
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
||||||
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
|
|
||||||
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
||||||
|
|
||||||
Random = random;
|
Random = random;
|
||||||
RandomStart = AvailableColumns == 8 ? 1 : 0;
|
RandomStart = TotalColumns == 8 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -45,14 +44,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// <returns>The column.</returns>
|
/// <returns>The column.</returns>
|
||||||
protected int GetColumn(float position, bool allowSpecial = false)
|
protected int GetColumn(float position, bool allowSpecial = false)
|
||||||
{
|
{
|
||||||
if (allowSpecial && AvailableColumns == 8)
|
if (allowSpecial && TotalColumns == 8)
|
||||||
{
|
{
|
||||||
const float local_x_divisor = 512f / 7;
|
const float local_x_divisor = 512f / 7;
|
||||||
return MathHelper.Clamp((int)Math.Floor(position / local_x_divisor), 0, 6) + 1;
|
return MathHelper.Clamp((int)Math.Floor(position / local_x_divisor), 0, 6) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
float localXDivisor = 512f / AvailableColumns;
|
float localXDivisor = 512f / TotalColumns;
|
||||||
return MathHelper.Clamp((int)Math.Floor(position / localXDivisor), 0, AvailableColumns - 1);
|
return MathHelper.Clamp((int)Math.Floor(position / localXDivisor), 0, TotalColumns - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
||||||
@ -12,11 +11,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal abstract class PatternGenerator
|
internal abstract class PatternGenerator
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The number of columns available to create the pattern.
|
|
||||||
/// </summary>
|
|
||||||
protected readonly int AvailableColumns;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The last pattern.
|
/// The last pattern.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -30,19 +24,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The beatmap which <see cref="HitObject"/> is a part of.
|
/// The beatmap which <see cref="HitObject"/> is a part of.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly Beatmap Beatmap;
|
protected readonly ManiaBeatmap Beatmap;
|
||||||
|
|
||||||
protected PatternGenerator(HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
protected readonly int TotalColumns;
|
||||||
|
|
||||||
|
protected PatternGenerator(HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||||
{
|
{
|
||||||
if (hitObject == null) throw new ArgumentNullException(nameof(hitObject));
|
if (hitObject == null) throw new ArgumentNullException(nameof(hitObject));
|
||||||
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
||||||
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
|
|
||||||
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
||||||
|
|
||||||
HitObject = hitObject;
|
HitObject = hitObject;
|
||||||
Beatmap = beatmap;
|
Beatmap = beatmap;
|
||||||
AvailableColumns = availableColumns;
|
|
||||||
PreviousPattern = previousPattern;
|
PreviousPattern = previousPattern;
|
||||||
|
|
||||||
|
TotalColumns = Beatmap.TotalColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
18
osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
Normal file
18
osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// 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.Mania.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines properties for each stage in a <see cref="ManiaPlayfield"/>.
|
||||||
|
/// </summary>
|
||||||
|
public struct StageDefinition
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The number of <see cref="Column"/>s which this stage contains.
|
||||||
|
/// </summary>
|
||||||
|
public int Columns;
|
||||||
|
}
|
||||||
|
}
|
34
osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs
Normal file
34
osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// 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.Configuration.Tracking;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Rulesets.Configuration;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Configuration
|
||||||
|
{
|
||||||
|
public class ManiaConfigManager : RulesetConfigManager<ManiaSetting>
|
||||||
|
{
|
||||||
|
public ManiaConfigManager(SettingsStore settings, RulesetInfo ruleset, int variant)
|
||||||
|
: base(settings, ruleset, variant)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void InitialiseDefaults()
|
||||||
|
{
|
||||||
|
base.InitialiseDefaults();
|
||||||
|
|
||||||
|
Set(ManiaSetting.ScrollTime, 1500.0, 50.0, 10000.0, 50.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
|
||||||
|
{
|
||||||
|
new TrackedSetting<double>(ManiaSetting.ScrollTime, v => new SettingDescription(v, "Scroll Time", $"{v}ms"))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ManiaSetting
|
||||||
|
{
|
||||||
|
ScrollTime
|
||||||
|
}
|
||||||
|
}
|
@ -1,200 +0,0 @@
|
|||||||
// Copyright (c) 2007-2017 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.Scoring;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Judgements
|
|
||||||
{
|
|
||||||
public class HitWindows
|
|
||||||
{
|
|
||||||
#region Constants
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// PERFECT hit window at OD = 10.
|
|
||||||
/// </summary>
|
|
||||||
private const double perfect_min = 27.8;
|
|
||||||
/// <summary>
|
|
||||||
/// PERFECT hit window at OD = 5.
|
|
||||||
/// </summary>
|
|
||||||
private const double perfect_mid = 38.8;
|
|
||||||
/// <summary>
|
|
||||||
/// PERFECT hit window at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double perfect_max = 44.8;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// GREAT hit window at OD = 10.
|
|
||||||
/// </summary>
|
|
||||||
private const double great_min = 68;
|
|
||||||
/// <summary>
|
|
||||||
/// GREAT hit window at OD = 5.
|
|
||||||
/// </summary>
|
|
||||||
private const double great_mid = 98;
|
|
||||||
/// <summary>
|
|
||||||
/// GREAT hit window at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double great_max = 128;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// GOOD hit window at OD = 10.
|
|
||||||
/// </summary>
|
|
||||||
private const double good_min = 134;
|
|
||||||
/// <summary>
|
|
||||||
/// GOOD hit window at OD = 5.
|
|
||||||
/// </summary>
|
|
||||||
private const double good_mid = 164;
|
|
||||||
/// <summary>
|
|
||||||
/// GOOD hit window at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double good_max = 194;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// OK hit window at OD = 10.
|
|
||||||
/// </summary>
|
|
||||||
private const double ok_min = 194;
|
|
||||||
/// <summary>
|
|
||||||
/// OK hit window at OD = 5.
|
|
||||||
/// </summary>
|
|
||||||
private const double ok_mid = 224;
|
|
||||||
/// <summary>
|
|
||||||
/// OK hit window at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double ok_max = 254;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// BAD hit window at OD = 10.
|
|
||||||
/// </summary>
|
|
||||||
private const double bad_min = 242;
|
|
||||||
/// <summary>
|
|
||||||
/// BAD hit window at OD = 5.
|
|
||||||
/// </summary>
|
|
||||||
private const double bad_mid = 272;
|
|
||||||
/// <summary>
|
|
||||||
/// BAD hit window at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double bad_max = 302;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// MISS hit window at OD = 10.
|
|
||||||
/// </summary>
|
|
||||||
private const double miss_min = 316;
|
|
||||||
/// <summary>
|
|
||||||
/// MISS hit window at OD = 5.
|
|
||||||
/// </summary>
|
|
||||||
private const double miss_mid = 346;
|
|
||||||
/// <summary>
|
|
||||||
/// MISS hit window at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double miss_max = 376;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hit window for a PERFECT hit.
|
|
||||||
/// </summary>
|
|
||||||
public double Perfect = perfect_mid;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hit window for a GREAT hit.
|
|
||||||
/// </summary>
|
|
||||||
public double Great = great_mid;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hit window for a GOOD hit.
|
|
||||||
/// </summary>
|
|
||||||
public double Good = good_mid;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hit window for an OK hit.
|
|
||||||
/// </summary>
|
|
||||||
public double Ok = ok_mid;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hit window for a BAD hit.
|
|
||||||
/// </summary>
|
|
||||||
public double Bad = bad_mid;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hit window for a MISS hit.
|
|
||||||
/// </summary>
|
|
||||||
public double Miss = miss_mid;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs default hit windows.
|
|
||||||
/// </summary>
|
|
||||||
public HitWindows()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs hit windows by fitting a parameter to a 2-part piecewise linear function for each hit window.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="difficulty">The parameter.</param>
|
|
||||||
public HitWindows(double difficulty)
|
|
||||||
{
|
|
||||||
Perfect = BeatmapDifficulty.DifficultyRange(difficulty, perfect_max, perfect_mid, perfect_min);
|
|
||||||
Great = BeatmapDifficulty.DifficultyRange(difficulty, great_max, great_mid, great_min);
|
|
||||||
Good = BeatmapDifficulty.DifficultyRange(difficulty, good_max, good_mid, good_min);
|
|
||||||
Ok = BeatmapDifficulty.DifficultyRange(difficulty, ok_max, ok_mid, ok_min);
|
|
||||||
Bad = BeatmapDifficulty.DifficultyRange(difficulty, bad_max, bad_mid, bad_min);
|
|
||||||
Miss = BeatmapDifficulty.DifficultyRange(difficulty, miss_max, miss_mid, miss_min);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves the hit result for a time offset.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hitOffset">The time offset.</param>
|
|
||||||
/// <returns>The hit result, or null if the time offset results in a miss.</returns>
|
|
||||||
public HitResult? ResultFor(double hitOffset)
|
|
||||||
{
|
|
||||||
if (hitOffset <= Perfect / 2)
|
|
||||||
return HitResult.Perfect;
|
|
||||||
if (hitOffset <= Great / 2)
|
|
||||||
return HitResult.Great;
|
|
||||||
if (hitOffset <= Good / 2)
|
|
||||||
return HitResult.Good;
|
|
||||||
if (hitOffset <= Ok / 2)
|
|
||||||
return HitResult.Ok;
|
|
||||||
if (hitOffset <= Bad / 2)
|
|
||||||
return HitResult.Meh;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs new hit windows which have been multiplied by a value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="windows">The original hit windows.</param>
|
|
||||||
/// <param name="value">The value to multiply each hit window by.</param>
|
|
||||||
public static HitWindows operator *(HitWindows windows, double value)
|
|
||||||
{
|
|
||||||
return new HitWindows
|
|
||||||
{
|
|
||||||
Perfect = windows.Perfect * value,
|
|
||||||
Great = windows.Great * value,
|
|
||||||
Good = windows.Good * value,
|
|
||||||
Ok = windows.Ok * value,
|
|
||||||
Bad = windows.Bad * value,
|
|
||||||
Miss = windows.Miss * value
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs new hit windows which have been divided by a value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="windows">The original hit windows.</param>
|
|
||||||
/// <param name="value">The value to divide each hit window by.</param>
|
|
||||||
public static HitWindows operator /(HitWindows windows, double value)
|
|
||||||
{
|
|
||||||
return new HitWindows
|
|
||||||
{
|
|
||||||
Perfect = windows.Perfect / value,
|
|
||||||
Great = windows.Great / value,
|
|
||||||
Good = windows.Good / value,
|
|
||||||
Ok = windows.Ok / value,
|
|
||||||
Bad = windows.Bad / value,
|
|
||||||
Miss = windows.Miss / value
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania
|
namespace osu.Game.Rulesets.Mania
|
||||||
{
|
{
|
||||||
@ -18,6 +17,6 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
|
|
||||||
public override double Calculate(Dictionary<string, double> categoryDifficulty = null) => 0;
|
public override double Calculate(Dictionary<string, double> categoryDifficulty = null) => 0;
|
||||||
|
|
||||||
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter(Beatmap beatmap) => new ManiaBeatmapConverter(true, (int)Math.Max(1, Math.Round(beatmap.BeatmapInfo.BaseDifficulty.CircleSize)));
|
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter(Beatmap beatmap) => new ManiaBeatmapConverter(true, beatmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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.ComponentModel;
|
using System.ComponentModel;
|
||||||
@ -17,8 +17,13 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
|
|
||||||
public enum ManiaAction
|
public enum ManiaAction
|
||||||
{
|
{
|
||||||
[Description("Special")]
|
[Description("Special 1")]
|
||||||
Special,
|
Special1 = 1,
|
||||||
|
[Description("Special 2")]
|
||||||
|
Special2,
|
||||||
|
|
||||||
|
// This offsets the start value of normal keys in-case we add more special keys
|
||||||
|
// above at a later time, without breaking replays/configs.
|
||||||
[Description("Key 1")]
|
[Description("Key 1")]
|
||||||
Key1 = 10,
|
Key1 = 10,
|
||||||
[Description("Key 2")]
|
[Description("Key 2")]
|
||||||
@ -36,6 +41,24 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
[Description("Key 8")]
|
[Description("Key 8")]
|
||||||
Key8,
|
Key8,
|
||||||
[Description("Key 9")]
|
[Description("Key 9")]
|
||||||
Key9
|
Key9,
|
||||||
|
[Description("Key 10")]
|
||||||
|
Key10,
|
||||||
|
[Description("Key 11")]
|
||||||
|
Key11,
|
||||||
|
[Description("Key 12")]
|
||||||
|
Key12,
|
||||||
|
[Description("Key 13")]
|
||||||
|
Key13,
|
||||||
|
[Description("Key 14")]
|
||||||
|
Key14,
|
||||||
|
[Description("Key 15")]
|
||||||
|
Key15,
|
||||||
|
[Description("Key 16")]
|
||||||
|
Key16,
|
||||||
|
[Description("Key 17")]
|
||||||
|
Key17,
|
||||||
|
[Description("Key 18")]
|
||||||
|
Key18,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
// Copyright (c) 2007-2017 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.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Mods;
|
using osu.Game.Rulesets.Mania.Mods;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
@ -86,7 +88,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
new ManiaModRandom(),
|
new ManiaModRandom(),
|
||||||
new ManiaModKeyCoop(),
|
new ManiaModDualStages(),
|
||||||
new MultiMod
|
new MultiMod
|
||||||
{
|
{
|
||||||
Mods = new Mod[]
|
Mods = new Mod[]
|
||||||
@ -95,7 +97,6 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
new ModCinema(),
|
new ModCinema(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
new ManiaModGravity()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -113,47 +114,194 @@ 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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<int> AvailableVariants => new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
public override IEnumerable<int> AvailableVariants
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
for (int i = 1; i <= 9; i++)
|
||||||
|
yield return (int)PlayfieldType.Single + i;
|
||||||
|
for (int i = 2; i <= 18; i += 2)
|
||||||
|
yield return (int)PlayfieldType.Dual + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0)
|
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0)
|
||||||
{
|
{
|
||||||
var leftKeys = new[]
|
switch (getPlayfieldType(variant))
|
||||||
{
|
{
|
||||||
InputKey.A,
|
case PlayfieldType.Single:
|
||||||
InputKey.S,
|
return new VariantMappingGenerator
|
||||||
InputKey.D,
|
{
|
||||||
InputKey.F
|
LeftKeys = new[]
|
||||||
};
|
{
|
||||||
|
InputKey.A,
|
||||||
|
InputKey.S,
|
||||||
|
InputKey.D,
|
||||||
|
InputKey.F
|
||||||
|
},
|
||||||
|
RightKeys = new[]
|
||||||
|
{
|
||||||
|
InputKey.J,
|
||||||
|
InputKey.K,
|
||||||
|
InputKey.L,
|
||||||
|
InputKey.Semicolon
|
||||||
|
},
|
||||||
|
SpecialKey = InputKey.Space,
|
||||||
|
SpecialAction = ManiaAction.Special1,
|
||||||
|
NormalActionStart = ManiaAction.Key1,
|
||||||
|
}.GenerateKeyBindingsFor(variant, out _);
|
||||||
|
case PlayfieldType.Dual:
|
||||||
|
int keys = getDualStageKeyCount(variant);
|
||||||
|
|
||||||
var rightKeys = new[]
|
var stage1Bindings = new VariantMappingGenerator
|
||||||
{
|
{
|
||||||
InputKey.J,
|
LeftKeys = new[]
|
||||||
InputKey.K,
|
{
|
||||||
InputKey.L,
|
InputKey.Number1,
|
||||||
InputKey.Semicolon
|
InputKey.Number2,
|
||||||
};
|
InputKey.Number3,
|
||||||
|
InputKey.Number4,
|
||||||
|
},
|
||||||
|
RightKeys = new[]
|
||||||
|
{
|
||||||
|
InputKey.Z,
|
||||||
|
InputKey.X,
|
||||||
|
InputKey.C,
|
||||||
|
InputKey.V
|
||||||
|
},
|
||||||
|
SpecialKey = InputKey.Tilde,
|
||||||
|
SpecialAction = ManiaAction.Special1,
|
||||||
|
NormalActionStart = ManiaAction.Key1
|
||||||
|
}.GenerateKeyBindingsFor(keys, out var nextNormal);
|
||||||
|
|
||||||
ManiaAction currentKey = ManiaAction.Key1;
|
var stage2Bindings = new VariantMappingGenerator
|
||||||
|
{
|
||||||
|
LeftKeys = new[]
|
||||||
|
{
|
||||||
|
InputKey.Number7,
|
||||||
|
InputKey.Number8,
|
||||||
|
InputKey.Number9,
|
||||||
|
InputKey.Number0
|
||||||
|
},
|
||||||
|
RightKeys = new[]
|
||||||
|
{
|
||||||
|
InputKey.O,
|
||||||
|
InputKey.P,
|
||||||
|
InputKey.BracketLeft,
|
||||||
|
InputKey.BracketRight
|
||||||
|
},
|
||||||
|
SpecialKey = InputKey.BackSlash,
|
||||||
|
SpecialAction = ManiaAction.Special2,
|
||||||
|
NormalActionStart = nextNormal
|
||||||
|
}.GenerateKeyBindingsFor(keys, out _);
|
||||||
|
|
||||||
var bindings = new List<KeyBinding>();
|
return stage1Bindings.Concat(stage2Bindings);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = leftKeys.Length - variant / 2; i < leftKeys.Length; i++)
|
return new KeyBinding[0];
|
||||||
bindings.Add(new KeyBinding(leftKeys[i], currentKey++));
|
|
||||||
|
|
||||||
for (int i = 0; i < variant / 2; i++)
|
|
||||||
bindings.Add(new KeyBinding(rightKeys[i], currentKey++));
|
|
||||||
|
|
||||||
if (variant % 2 == 1)
|
|
||||||
bindings.Add(new KeyBinding(InputKey.Space, ManiaAction.Special));
|
|
||||||
|
|
||||||
return bindings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetVariantName(int variant) => $"{variant}K";
|
public override string GetVariantName(int variant)
|
||||||
|
{
|
||||||
|
switch (getPlayfieldType(variant))
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return $"{variant}K";
|
||||||
|
case PlayfieldType.Dual:
|
||||||
|
{
|
||||||
|
var keys = getDualStageKeyCount(variant);
|
||||||
|
return $"{keys}K + {keys}K";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the number of keys for each stage in a <see cref="PlayfieldType.Dual"/> variant.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variant">The variant.</param>
|
||||||
|
private int getDualStageKeyCount(int variant) => (variant - (int)PlayfieldType.Dual) / 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the <see cref="PlayfieldType"/> that corresponds to a variant value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variant">The variant value.</param>
|
||||||
|
/// <returns>The <see cref="PlayfieldType"/> that corresponds to <paramref name="variant"/>.</returns>
|
||||||
|
private PlayfieldType getPlayfieldType(int variant)
|
||||||
|
{
|
||||||
|
return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast<int>().OrderByDescending(i => i).First(v => variant >= v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class VariantMappingGenerator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All the <see cref="InputKey"/>s available to the left hand.
|
||||||
|
/// </summary>
|
||||||
|
public InputKey[] LeftKeys;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All the <see cref="InputKey"/>s available to the right hand.
|
||||||
|
/// </summary>
|
||||||
|
public InputKey[] RightKeys;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="InputKey"/> for the special key.
|
||||||
|
/// </summary>
|
||||||
|
public InputKey SpecialKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ManiaAction"/> at which the normal columns should begin.
|
||||||
|
/// </summary>
|
||||||
|
public ManiaAction NormalActionStart;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="ManiaAction"/> for the special column.
|
||||||
|
/// </summary>
|
||||||
|
public ManiaAction SpecialAction;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a list of <see cref="KeyBinding"/>s for a specific number of columns.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="columns">The number of columns that need to be bound.</param>
|
||||||
|
/// <param name="nextNormalAction">The next <see cref="ManiaAction"/> to use for normal columns.</param>
|
||||||
|
/// <returns>The keybindings.</returns>
|
||||||
|
public IEnumerable<KeyBinding> GenerateKeyBindingsFor(int columns, out ManiaAction nextNormalAction)
|
||||||
|
{
|
||||||
|
ManiaAction currentNormalAction = NormalActionStart;
|
||||||
|
|
||||||
|
var bindings = new List<KeyBinding>();
|
||||||
|
|
||||||
|
for (int i = LeftKeys.Length - columns / 2; i < LeftKeys.Length; i++)
|
||||||
|
bindings.Add(new KeyBinding(LeftKeys[i], currentNormalAction++));
|
||||||
|
|
||||||
|
for (int i = 0; i < columns / 2; i++)
|
||||||
|
bindings.Add(new KeyBinding(RightKeys[i], currentNormalAction++));
|
||||||
|
|
||||||
|
if (columns % 2 == 1)
|
||||||
|
bindings.Add(new KeyBinding(SpecialKey, SpecialAction));
|
||||||
|
|
||||||
|
nextNormalAction = currentNormalAction;
|
||||||
|
return bindings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PlayfieldType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Columns are grouped into a single stage.
|
||||||
|
/// Number of columns in this stage lies at (item - Single).
|
||||||
|
/// </summary>
|
||||||
|
Single = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Columns are grouped into two stages.
|
||||||
|
/// Overall number of columns lies at (item - Dual), further computation is required for
|
||||||
|
/// number of columns in each individual stage.
|
||||||
|
/// </summary>
|
||||||
|
Dual = 1000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2007-2017 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;
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
// Copyright (c) 2007-2017 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);
|
|
||||||
}
|
|
||||||
}
|
|
15
osu.Game.Rulesets.Mania/Mods/IPlayfieldTypeMod.cs
Normal file
15
osu.Game.Rulesets.Mania/Mods/IPlayfieldTypeMod.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 osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public interface IPlayfieldTypeMod : IApplicableMod
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="PlayfieldType"/> which this <see cref="IPlayfieldTypeMod"/> requires.
|
||||||
|
/// </summary>
|
||||||
|
PlayfieldType PlayfieldType { get; }
|
||||||
|
}
|
||||||
|
}
|
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,187 +0,0 @@
|
|||||||
// Copyright (c) 2007-2017 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.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).AvailableColumns;
|
|
||||||
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
|
|
||||||
{
|
|
||||||
// TODO: implement using the IApplicable interface. Haven't done so yet because KeyCount isn't even hooked up at the moment.
|
|
||||||
|
|
||||||
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 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;
|
||||||
|
}
|
||||||
|
}
|
53
osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs
Normal file
53
osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// 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.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
|
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 ManiaModDualStages : Mod, IPlayfieldTypeMod, IApplicableToBeatmapConverter<ManiaHitObject>, IApplicableToRulesetContainer<ManiaHitObject>
|
||||||
|
{
|
||||||
|
public override string Name => "Dual Stages";
|
||||||
|
public override string ShortenedName => "DS";
|
||||||
|
public override string Description => @"Double the stages, double the fun!";
|
||||||
|
public override double ScoreMultiplier => 1;
|
||||||
|
public override bool Ranked => false;
|
||||||
|
|
||||||
|
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 *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
||||||
|
{
|
||||||
|
var mrc = (ManiaRulesetContainer)rulesetContainer;
|
||||||
|
|
||||||
|
// Although this can work, for now let's not allow keymods for mania-specific beatmaps
|
||||||
|
if (mrc.IsForCurrentRuleset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var newDefinitions = new List<StageDefinition>();
|
||||||
|
foreach (var existing in mrc.Beatmap.Stages)
|
||||||
|
{
|
||||||
|
newDefinitions.Add(new StageDefinition { Columns = existing.Columns / 2 });
|
||||||
|
newDefinitions.Add(new StageDefinition { Columns = existing.Columns / 2 });
|
||||||
|
}
|
||||||
|
|
||||||
|
mrc.Beatmap.Stages = newDefinitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayfieldType PlayfieldType => PlayfieldType.Dual;
|
||||||
|
}
|
||||||
|
}
|
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-2017 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";
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user