mirror of
https://github.com/ppy/osu.git
synced 2026-05-14 07:32:36 +08:00
Compare commits
1098 Commits
Vendored
+42
-35
@@ -2,63 +2,70 @@
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"command": "msbuild",
|
||||
"type": "shell",
|
||||
"suppressTaskName": true,
|
||||
"args": [
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/property:DebugType=portable",
|
||||
"/verbosity:minimal",
|
||||
"/m" //parallel compiling support.
|
||||
],
|
||||
"tasks": [{
|
||||
"taskName": "Build (Debug)",
|
||||
"label": "Build (Debug)",
|
||||
"type": "shell",
|
||||
"command": "msbuild",
|
||||
"args": [
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/p:DebugType=portable",
|
||||
"/m",
|
||||
"/v:m"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$msCompile"
|
||||
]
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"taskName": "Build (Release)",
|
||||
"label": "Build (Release)",
|
||||
"type": "shell",
|
||||
"command": "msbuild",
|
||||
"args": [
|
||||
"/p:Configuration=Release",
|
||||
"/p:DebugType=portable",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/v:m"
|
||||
],
|
||||
"group": "build",
|
||||
"args": [
|
||||
"/property:Configuration=Release"
|
||||
],
|
||||
"problemMatcher": [
|
||||
"$msCompile"
|
||||
]
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"taskName": "Clean (Debug)",
|
||||
"label": "Clean (Debug)",
|
||||
"type": "shell",
|
||||
"command": "msbuild",
|
||||
"args": [
|
||||
"/target:Clean"
|
||||
"/p:DebugType=portable",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/t:Clean",
|
||||
"/v:m"
|
||||
],
|
||||
"problemMatcher": [
|
||||
"$msCompile"
|
||||
]
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"taskName": "Clean (Release)",
|
||||
"label": "Clean (Release)",
|
||||
"type": "shell",
|
||||
"command": "msbuild",
|
||||
"args": [
|
||||
"/target:Clean",
|
||||
"/property:Configuration=Release"
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/p:DebugType=portable",
|
||||
"/m",
|
||||
"/t:Clean",
|
||||
"/v:m"
|
||||
],
|
||||
"problemMatcher": [
|
||||
"$msCompile"
|
||||
]
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"taskName": "Clean All",
|
||||
"label": "Clean All",
|
||||
"dependsOn": [
|
||||
"Clean (Debug)",
|
||||
"Clean (Release)"
|
||||
],
|
||||
"problemMatcher": [
|
||||
"$msCompile"
|
||||
]
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# Linux
|
||||
### 1. Requirements:
|
||||
Mono >= 5.4.0 (>= 5.8.0 recommended)
|
||||
Please check [here](http://www.mono-project.com/download/) for stable or [here](http://www.mono-project.com/download/alpha/) for an alpha release.
|
||||
NuGet >= 4.4.0
|
||||
msbuild
|
||||
git
|
||||
|
||||
### 2. Cloning project
|
||||
Clone the entire repository with submodules using
|
||||
```
|
||||
git clone https://github.com/ppy/osu --recursive
|
||||
```
|
||||
Then restore NuGet packages from the repository
|
||||
```
|
||||
nuget restore
|
||||
```
|
||||
### 3. Compiling
|
||||
Simply run `msbuild` where `osu.sln` is located, this will create all binaries in `osu/osu.Desktop/bin/Debug`.
|
||||
### 4. Optimizing
|
||||
If you want additional performance you can change build type to Release with
|
||||
```
|
||||
msbuild -p:Configuration=Release
|
||||
```
|
||||
Additionally, mono provides an AOT utility which attempts to precompile binaries. You can utilize that by running
|
||||
```
|
||||
mono --aot ./osu\!.exe
|
||||
```
|
||||
### 5. Troubleshooting
|
||||
You may run into trouble with NuGet versioning, as the one in packaging system is almost always out of date. Simply run
|
||||
```
|
||||
nuget
|
||||
sudo nuget update -self
|
||||
```
|
||||
**Warning** NuGet creates few config files when it's run for the first time.
|
||||
Do not run NuGet as root on the first run or you might run into very peculiar issues.
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="opentk-develop" value="https://www.myget.org/F/opentk-develop" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
@@ -8,8 +8,11 @@ This is still heavily under development and is not intended for end-user use. Th
|
||||
|
||||
# Requirements
|
||||
|
||||
- A desktop platform which can compile .NET 4.5 (tested on macOS, linux and windows). We recommend using [Visual Studio Code](https://code.visualstudio.com/) (all platforms) or [Visual Studio Community Edition](https://www.visualstudio.com/) (windows only), both of which are free.
|
||||
- Make sure you initialise and keep submodules up-to-date.
|
||||
- A desktop platform that can compile .NET 4.6.1. We recommend using [Visual Studio Community Edition](https://www.visualstudio.com/) (Windows), [Visual Studio for Mac](https://www.visualstudio.com/vs/visual-studio-mac/) (macOS) or [MonoDevelop](http://www.monodevelop.com/download/) (Linux), all of which are free. [Visual Studio Code](https://code.visualstudio.com/) may also be used but requires further setup steps which are not covered here.
|
||||
|
||||
# Getting Started
|
||||
- Clone the repository including submodules (`git clone --recurse-submodules https://github.com/ppy/osu`)
|
||||
- Build in your IDE of choice (recommended IDEs automatically restore nuget packages; if you are using an alternative make sure to `nuget restore`)
|
||||
|
||||
# Contributing
|
||||
|
||||
|
||||
+1
-1
Submodule osu-framework updated: 797a351db2...8f36ddab94
+1
-1
Submodule osu-resources updated: 4287ee8043...7724abdf1d
@@ -1,6 +1,6 @@
|
||||
<?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
|
||||
-->
|
||||
<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
|
||||
|
||||
using Newtonsoft.Json;
|
||||
@@ -13,4 +13,4 @@ namespace osu.Desktop.Deploy
|
||||
[JsonProperty(@"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
|
||||
|
||||
using Newtonsoft.Json;
|
||||
@@ -25,4 +25,4 @@ namespace osu.Desktop.Deploy
|
||||
[JsonProperty(@"upload_url")]
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?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
|
||||
-->
|
||||
<packages>
|
||||
|
||||
@@ -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
|
||||
|
||||
using System;
|
||||
@@ -45,7 +45,7 @@ namespace osu.Desktop
|
||||
{
|
||||
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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
using osu.Framework.Platform;
|
||||
@@ -27,4 +27,4 @@ namespace osu.Desktop
|
||||
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
|
||||
|
||||
using System;
|
||||
@@ -31,7 +31,8 @@ namespace osu.Desktop.Overlays
|
||||
private OsuConfigManager config;
|
||||
private OsuGameBase game;
|
||||
|
||||
public override bool HandleInput => false;
|
||||
public override bool HandleKeyboardInput => false;
|
||||
public override bool HandleMouseInput => false;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config)
|
||||
@@ -110,7 +111,7 @@ namespace osu.Desktop.Overlays
|
||||
|
||||
// only show a notification if we've previously saved a version to the config file (ie. not the first run).
|
||||
if (!string.IsNullOrEmpty(lastVersion))
|
||||
Scheduler.AddDelayed(() => notificationOverlay.Post(new UpdateCompleteNotification(version)), 5000);
|
||||
notificationOverlay.Post(new UpdateCompleteNotification(version));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
using System;
|
||||
@@ -43,7 +43,6 @@ namespace osu.Desktop
|
||||
host.Run(new OsuGameDesktop(args));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
using System.Reflection;
|
||||
@@ -12,7 +12,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("ppy Pty Ltd")]
|
||||
[assembly: AssemblyProduct("osu!lazer")]
|
||||
[assembly: AssemblyCopyright("ppy Pty Ltd 2007-2017")]
|
||||
[assembly: AssemblyCopyright("ppy Pty Ltd 2007-2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
||||
@@ -135,8 +135,8 @@
|
||||
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\NuGet.Squirrel.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||
<HintPath>$(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll</HintPath>
|
||||
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4">
|
||||
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.3.0.11\lib\net45\OpenTK.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="SharpCompress, Version=0.18.1.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?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
|
||||
-->
|
||||
<packages>
|
||||
<package id="DeltaCompressionDotNet" version="1.1.0" targetFramework="net45" />
|
||||
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net45" />
|
||||
<package id="OpenTK" version="3.0.0-git00009" targetFramework="net461" />
|
||||
<package id="ppy.OpenTK" version="3.0.11" targetFramework="net461" />
|
||||
<package id="SharpCompress" version="0.18.1" targetFramework="net461" />
|
||||
<package id="Splat" version="2.0.0" targetFramework="net45" />
|
||||
<package id="SQLitePCLRaw.bundle_green" version="1.1.8" targetFramework="net461" />
|
||||
|
||||
@@ -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
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
@@ -11,7 +11,7 @@ using osu.Game.Rulesets.Objects;
|
||||
|
||||
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) };
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
var curveData = obj as IHasCurve;
|
||||
var positionData = obj as IHasXPosition;
|
||||
var comboData = obj as IHasCombo;
|
||||
var endTime = obj as IHasEndTime;
|
||||
|
||||
if (positionData == null)
|
||||
yield break;
|
||||
@@ -42,6 +43,19 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
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
|
||||
{
|
||||
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
|
||||
|
||||
using System;
|
||||
@@ -12,14 +12,14 @@ using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
{
|
||||
internal class CatchBeatmapProcessor : BeatmapProcessor<CatchHitObject>
|
||||
public class CatchBeatmapProcessor : BeatmapProcessor<CatchHitObject>
|
||||
{
|
||||
public override void PostProcess(Beatmap<CatchHitObject> beatmap)
|
||||
{
|
||||
if (beatmap.ComboColors.Count == 0)
|
||||
return;
|
||||
|
||||
int comboIndex = 0;
|
||||
int index = 0;
|
||||
int colourIndex = 0;
|
||||
|
||||
CatchHitObject lastObj = null;
|
||||
@@ -31,12 +31,10 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
if (obj.NewCombo)
|
||||
{
|
||||
if (lastObj != null) lastObj.LastInCombo = true;
|
||||
|
||||
comboIndex = 0;
|
||||
colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
|
||||
}
|
||||
|
||||
obj.ComboIndex = comboIndex++;
|
||||
obj.IndexInBeatmap = index++;
|
||||
obj.ComboColour = beatmap.ComboColors[colourIndex];
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
using System.ComponentModel;
|
||||
@@ -22,6 +22,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
[Description("Move right")]
|
||||
MoveRight,
|
||||
[Description("Engage dash")]
|
||||
Dash
|
||||
Dash,
|
||||
PositionUpdate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
@@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
Mods = new Mod[]
|
||||
{
|
||||
new ModAutoplay(),
|
||||
new CatchModAutoplay(),
|
||||
new ModCinema(),
|
||||
},
|
||||
},
|
||||
@@ -93,13 +93,15 @@ namespace osu.Game.Rulesets.Catch
|
||||
|
||||
public override string Description => "osu!catch";
|
||||
|
||||
public override string ShortName => "fruits";
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new CatchDifficultyCalculator(beatmap);
|
||||
|
||||
public override int LegacyID => 2;
|
||||
|
||||
public CatchRuleset(RulesetInfo rulesetInfo)
|
||||
public CatchRuleset(RulesetInfo rulesetInfo = null)
|
||||
: 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
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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.";
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
@@ -15,8 +15,11 @@ namespace osu.Game.Rulesets.Catch.Objects
|
||||
|
||||
public float X { get; set; }
|
||||
|
||||
public Color4 ComboColour { get; set; } = Color4.Gray;
|
||||
public int ComboIndex { get; set; }
|
||||
public Color4 ComboColour { get; set; }
|
||||
|
||||
public int IndexInBeatmap { get; set; }
|
||||
|
||||
public virtual FruitVisualRepresentation VisualRepresentation => (FruitVisualRepresentation)(IndexInBeatmap % 4);
|
||||
|
||||
public virtual bool NewCombo { get; set; }
|
||||
|
||||
@@ -37,11 +40,20 @@ namespace osu.Game.Rulesets.Catch.Objects
|
||||
/// </summary>
|
||||
public CatchHitObject HyperDashTarget;
|
||||
|
||||
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
||||
protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
||||
{
|
||||
base.ApplyDefaults(controlPointInfo, difficulty);
|
||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||
|
||||
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,14 +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
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using OpenTK;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
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
|
||||
where TObject : CatchHitObject
|
||||
{
|
||||
@@ -18,27 +32,29 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
: base(hitObject)
|
||||
{
|
||||
HitObject = hitObject;
|
||||
|
||||
Scale = new Vector2(HitObject.Scale);
|
||||
Anchor = Anchor.BottomLeft;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class DrawableCatchHitObject : DrawableScrollingHitObject<CatchHitObject>
|
||||
public abstract class DrawableCatchHitObject : DrawableHitObject<CatchHitObject>
|
||||
{
|
||||
public virtual bool CanBePlated => false;
|
||||
|
||||
protected DrawableCatchHitObject(CatchHitObject hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
RelativePositionAxes = Axes.Both;
|
||||
RelativePositionAxes = Axes.X;
|
||||
X = hitObject.X;
|
||||
Y = (float)HitObject.StartTime;
|
||||
}
|
||||
|
||||
public Func<CatchHitObject, bool> CheckPosition;
|
||||
|
||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||
{
|
||||
if (CheckPosition == null) return;
|
||||
|
||||
if (timeOffset > 0)
|
||||
AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss });
|
||||
AddJudgement(new Judgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss });
|
||||
}
|
||||
|
||||
private const float preempt = 1000;
|
||||
@@ -46,17 +62,21 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
using (BeginAbsoluteSequence(HitObject.StartTime - preempt))
|
||||
{
|
||||
// animation
|
||||
this.FadeIn(200);
|
||||
}
|
||||
|
||||
switch (state)
|
||||
var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;
|
||||
|
||||
using (BeginAbsoluteSequence(endTime, true))
|
||||
{
|
||||
case ArmedState.Miss:
|
||||
using (BeginAbsoluteSequence(HitObject.StartTime, true))
|
||||
this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out);
|
||||
break;
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Miss:
|
||||
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
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
@@ -8,15 +8,13 @@ using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
public class DrawableDroplet : DrawableCatchHitObject<Droplet>
|
||||
public class DrawableDroplet : PalpableCatchHitObject<Droplet>
|
||||
{
|
||||
public DrawableDroplet(Droplet h)
|
||||
: base(h)
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Size = new Vector2(Pulp.PULP_SIZE);
|
||||
|
||||
Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS) / 4;
|
||||
AccentColour = h.ComboColour;
|
||||
Masking = false;
|
||||
}
|
||||
@@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
Child = new Pulp
|
||||
{
|
||||
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
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
||||
using OpenTK;
|
||||
@@ -11,14 +14,16 @@ using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
public class DrawableFruit : DrawableCatchHitObject<Fruit>
|
||||
public class DrawableFruit : PalpableCatchHitObject<Fruit>
|
||||
{
|
||||
private Circle border;
|
||||
|
||||
public DrawableFruit(Fruit h)
|
||||
: base(h)
|
||||
{
|
||||
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;
|
||||
Masking = false;
|
||||
|
||||
@@ -28,48 +33,34 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Children = new Framework.Graphics.Drawable[]
|
||||
Children = new[]
|
||||
{
|
||||
//todo: share this more
|
||||
new BufferedContainer
|
||||
createPulp(HitObject.VisualRepresentation),
|
||||
border = new Circle
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
CacheDrawnFrameBuffer = true,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
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[]
|
||||
{
|
||||
new Pulp
|
||||
new Box
|
||||
{
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
AccentColour = AccentColour,
|
||||
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,
|
||||
},
|
||||
AlwaysPresent = true,
|
||||
Colour = AccentColour,
|
||||
Alpha = 0,
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (HitObject.HyperDash)
|
||||
@@ -82,9 +73,205 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
AccentColour = Color4.Red,
|
||||
Blending = BlendingMode.Additive,
|
||||
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,9 +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
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using OpenTK;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
@@ -12,41 +13,26 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
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;
|
||||
Height = (float)HitObject.Duration;
|
||||
Origin = Anchor.BottomLeft;
|
||||
X = 0;
|
||||
|
||||
Child = dropletContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime),
|
||||
RelativeChildSize = new Vector2(1, (float)HitObject.Duration)
|
||||
};
|
||||
Child = dropletContainer = new Container { RelativeSizeAxes = Axes.Both, };
|
||||
|
||||
foreach (CatchHitObject tick in s.Ticks)
|
||||
{
|
||||
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));
|
||||
}
|
||||
foreach (var o in s.NestedHitObjects.Cast<CatchHitObject>())
|
||||
AddNested(getVisualRepresentation?.Invoke(o));
|
||||
}
|
||||
|
||||
protected override void AddNested(DrawableHitObject<CatchHitObject> h)
|
||||
protected override void AddNested(DrawableHitObject h)
|
||||
{
|
||||
((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false;
|
||||
var catchObject = (DrawableCatchHitObject)h;
|
||||
|
||||
catchObject.CheckPosition = o => CheckPosition?.Invoke(o) ?? false;
|
||||
catchObject.AccentColour = HitObject.ComboColour;
|
||||
|
||||
dropletContainer.Add(h);
|
||||
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
|
||||
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
@@ -6,18 +6,17 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
|
||||
{
|
||||
public class Pulp : Circle, IHasAccentColour
|
||||
{
|
||||
public const float PULP_SIZE = (float)CatchHitObject.OBJECT_RADIUS / 2.2f;
|
||||
|
||||
public Pulp()
|
||||
{
|
||||
Size = new Vector2(PULP_SIZE);
|
||||
RelativePositionAxes = Axes.Both;
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
Blending = BlendingMode.Additive;
|
||||
Colour = Color4.White.Opacity(0.9f);
|
||||
@@ -34,8 +33,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Radius = 5,
|
||||
Colour = accentColour.Lighten(100),
|
||||
Radius = 8,
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
using System;
|
||||
@@ -11,7 +11,6 @@ using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using OpenTK;
|
||||
using osu.Framework.Lists;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Objects
|
||||
{
|
||||
@@ -29,9 +28,9 @@ namespace osu.Game.Rulesets.Catch.Objects
|
||||
public double Velocity;
|
||||
public double TickDistance;
|
||||
|
||||
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
||||
protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
||||
{
|
||||
base.ApplyDefaults(controlPointInfo, difficulty);
|
||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||
|
||||
TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
|
||||
DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime);
|
||||
@@ -42,89 +41,89 @@ namespace osu.Game.Rulesets.Catch.Objects
|
||||
TickDistance = scoringDistance / difficulty.SliderTickRate;
|
||||
}
|
||||
|
||||
public IEnumerable<CatchHitObject> Ticks
|
||||
protected override void CreateNestedHitObjects()
|
||||
{
|
||||
get
|
||||
base.CreateNestedHitObjects();
|
||||
|
||||
createTicks();
|
||||
}
|
||||
|
||||
private void createTicks()
|
||||
{
|
||||
if (TickDistance == 0)
|
||||
return;
|
||||
|
||||
var length = Curve.Distance;
|
||||
var tickDistance = Math.Min(TickDistance, length);
|
||||
var repeatDuration = length / Velocity;
|
||||
|
||||
var minDistanceFromEnd = Velocity * 0.01;
|
||||
|
||||
AddNested(new Fruit
|
||||
{
|
||||
SortedList<CatchHitObject> ticks = new SortedList<CatchHitObject>((a, b) => a.StartTime.CompareTo(b.StartTime));
|
||||
Samples = Samples,
|
||||
ComboColour = ComboColour,
|
||||
StartTime = StartTime,
|
||||
X = X
|
||||
});
|
||||
|
||||
if (TickDistance == 0)
|
||||
return ticks;
|
||||
for (var repeat = 0; repeat < RepeatCount; repeat++)
|
||||
{
|
||||
var repeatStartTime = StartTime + repeat * repeatDuration;
|
||||
var reversed = repeat % 2 == 1;
|
||||
|
||||
var length = Curve.Distance;
|
||||
var tickDistance = Math.Min(TickDistance, length);
|
||||
var repeatDuration = length / Velocity;
|
||||
|
||||
var minDistanceFromEnd = Velocity * 0.01;
|
||||
|
||||
ticks.Add(new Fruit
|
||||
for (var d = tickDistance; d <= length; d += tickDistance)
|
||||
{
|
||||
Samples = Samples,
|
||||
ComboColour = ComboColour,
|
||||
StartTime = StartTime,
|
||||
X = X
|
||||
});
|
||||
if (d > length - minDistanceFromEnd)
|
||||
break;
|
||||
|
||||
for (var repeat = 0; repeat < RepeatCount; repeat++)
|
||||
{
|
||||
var repeatStartTime = StartTime + repeat * repeatDuration;
|
||||
var reversed = repeat % 2 == 1;
|
||||
var timeProgress = d / length;
|
||||
var distanceProgress = reversed ? 1 - timeProgress : timeProgress;
|
||||
|
||||
for (var d = tickDistance; d <= length; d += tickDistance)
|
||||
var lastTickTime = repeatStartTime + timeProgress * repeatDuration;
|
||||
AddNested(new Droplet
|
||||
{
|
||||
if (d > length - minDistanceFromEnd)
|
||||
break;
|
||||
|
||||
var timeProgress = d / length;
|
||||
var distanceProgress = reversed ? 1 - timeProgress : timeProgress;
|
||||
|
||||
var lastTickTime = repeatStartTime + timeProgress * repeatDuration;
|
||||
ticks.Add(new Droplet
|
||||
{
|
||||
StartTime = lastTickTime,
|
||||
ComboColour = ComboColour,
|
||||
X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH,
|
||||
Samples = new SampleInfoList(Samples.Select(s => new SampleInfo
|
||||
{
|
||||
Bank = s.Bank,
|
||||
Name = @"slidertick",
|
||||
Volume = s.Volume
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
double tinyTickInterval = tickDistance / length * repeatDuration;
|
||||
while (tinyTickInterval > 100)
|
||||
tinyTickInterval /= 2;
|
||||
|
||||
for (double t = 0; t < repeatDuration; t += tinyTickInterval)
|
||||
{
|
||||
double progress = reversed ? 1 - t / repeatDuration : t / repeatDuration;
|
||||
|
||||
ticks.Add(new TinyDroplet
|
||||
{
|
||||
StartTime = repeatStartTime + t,
|
||||
ComboColour = ComboColour,
|
||||
X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH,
|
||||
Samples = new SampleInfoList(Samples.Select(s => new SampleInfo
|
||||
{
|
||||
Bank = s.Bank,
|
||||
Name = @"slidertick",
|
||||
Volume = s.Volume
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
ticks.Add(new Fruit
|
||||
{
|
||||
Samples = Samples,
|
||||
StartTime = lastTickTime,
|
||||
ComboColour = ComboColour,
|
||||
StartTime = repeatStartTime + repeatDuration,
|
||||
X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
|
||||
X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH,
|
||||
Samples = new List<SampleInfo>(Samples.Select(s => new SampleInfo
|
||||
{
|
||||
Bank = s.Bank,
|
||||
Name = @"slidertick",
|
||||
Volume = s.Volume
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
return ticks;
|
||||
double tinyTickInterval = tickDistance / length * repeatDuration;
|
||||
while (tinyTickInterval > 100)
|
||||
tinyTickInterval /= 2;
|
||||
|
||||
for (double t = 0; t < repeatDuration; t += tinyTickInterval)
|
||||
{
|
||||
double progress = reversed ? 1 - t / repeatDuration : t / repeatDuration;
|
||||
|
||||
AddNested(new TinyDroplet
|
||||
{
|
||||
StartTime = repeatStartTime + t,
|
||||
ComboColour = ComboColour,
|
||||
X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH,
|
||||
Samples = new List<SampleInfo>(Samples.Select(s => new SampleInfo
|
||||
{
|
||||
Bank = s.Bank,
|
||||
Name = @"slidertick",
|
||||
Volume = s.Volume
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
AddNested(new Fruit
|
||||
{
|
||||
Samples = Samples,
|
||||
ComboColour = ComboColour,
|
||||
StartTime = repeatStartTime + repeatDuration,
|
||||
X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +145,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
||||
set { Curve.ControlPoints = value; }
|
||||
}
|
||||
|
||||
public List<SampleInfoList> RepeatSamples { get; set; } = new List<SampleInfoList>();
|
||||
public List<List<SampleInfo>> RepeatSamples { get; set; } = new List<List<SampleInfo>>();
|
||||
|
||||
public CurveType CurveType
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
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
|
||||
|
||||
using System.Reflection;
|
||||
@@ -12,7 +12,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("ppy Pty Ltd")]
|
||||
[assembly: AssemblyProduct("osu.Game.Rulesets.Catch")]
|
||||
[assembly: AssemblyCopyright("ppy Pty Ltd 2007-2017")]
|
||||
[assembly: AssemblyCopyright("ppy Pty Ltd 2007-2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Replays
|
||||
{
|
||||
internal class CatchAutoGenerator : AutoGenerator<CatchHitObject>
|
||||
{
|
||||
public const double RELEASE_DELAY = 20;
|
||||
|
||||
public CatchAutoGenerator(Beatmap<CatchHitObject> beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
Replay = new Replay { User = new User { Username = @"Autoplay" } };
|
||||
}
|
||||
|
||||
protected Replay Replay;
|
||||
|
||||
public override Replay Generate()
|
||||
{
|
||||
// Todo: Realistically this shouldn't be needed, but the first frame is skipped with the way replays are currently handled
|
||||
Replay.Frames.Add(new CatchReplayFrame(-100000, 0));
|
||||
|
||||
foreach (var obj in Beatmap.HitObjects)
|
||||
{
|
||||
switch (obj)
|
||||
{
|
||||
case Fruit _:
|
||||
Replay.Frames.Add(new CatchReplayFrame(obj.StartTime, obj.X));
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var nestedObj in obj.NestedHitObjects.Cast<CatchHitObject>())
|
||||
{
|
||||
switch (nestedObj)
|
||||
{
|
||||
case BananaShower.Banana _:
|
||||
case TinyDroplet _:
|
||||
case Droplet _:
|
||||
Replay.Frames.Add(new CatchReplayFrame(nestedObj.StartTime, nestedObj.X));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Replay;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Replays
|
||||
{
|
||||
public class CatchFramedReplayInputHandler : FramedReplayInputHandler
|
||||
{
|
||||
public CatchFramedReplayInputHandler(Replay replay)
|
||||
: base(replay)
|
||||
{
|
||||
}
|
||||
|
||||
public override List<InputState> GetPendingStates() => new List<InputState>
|
||||
{
|
||||
new CatchReplayState
|
||||
{
|
||||
PressedActions = new List<CatchAction> { CatchAction.PositionUpdate },
|
||||
CatcherX = ((CatchReplayFrame)CurrentFrame).MouseX
|
||||
},
|
||||
new CatchReplayState { PressedActions = new List<CatchAction>() },
|
||||
};
|
||||
|
||||
public class CatchReplayState : ReplayState<CatchAction>
|
||||
{
|
||||
public float? CatcherX { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Replays;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Replays
|
||||
{
|
||||
public class CatchReplayFrame : ReplayFrame
|
||||
{
|
||||
public override bool IsImportant => MouseX > 0;
|
||||
|
||||
public CatchReplayFrame(double time, float? x = null)
|
||||
: base(time, x ?? -1, null, ReplayButtonState.None)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
// 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
|
||||
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Judgements;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Scoring
|
||||
{
|
||||
internal class CatchScoreProcessor : ScoreProcessor<CatchHitObject>
|
||||
public class CatchScoreProcessor : ScoreProcessor<CatchHitObject>
|
||||
{
|
||||
public CatchScoreProcessor(RulesetContainer<CatchHitObject> rulesetContainer)
|
||||
: base(rulesetContainer)
|
||||
@@ -21,23 +21,25 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
||||
{
|
||||
foreach (var obj in beatmap.HitObjects)
|
||||
{
|
||||
var stream = obj as JuiceStream;
|
||||
|
||||
if (stream != null)
|
||||
switch (obj)
|
||||
{
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
|
||||
foreach (var unused in stream.Ticks)
|
||||
case JuiceStream stream:
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
|
||||
continue;
|
||||
foreach (var _ in stream.NestedHitObjects.Cast<CatchHitObject>())
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
break;
|
||||
case BananaShower shower:
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
|
||||
foreach (var _ in shower.NestedHitObjects.Cast<CatchHitObject>())
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
break;
|
||||
case Fruit _:
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
break;
|
||||
}
|
||||
|
||||
var fruit = obj as Fruit;
|
||||
|
||||
if (fruit != null)
|
||||
AddJudgement(new CatchJudgement { Result = HitResult.Perfect });
|
||||
}
|
||||
|
||||
base.SimulateAutoplay(beatmap);
|
||||
|
||||
@@ -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
|
||||
|
||||
using NUnit.Framework;
|
||||
@@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
[Ignore("getting CI working")]
|
||||
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
|
||||
|
||||
using NUnit.Framework;
|
||||
@@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer
|
||||
{
|
||||
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
|
||||
|
||||
using System;
|
||||
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[Ignore("getting CI working")]
|
||||
internal class TestCaseCatcherArea : OsuTestCase
|
||||
public class TestCaseCatcherArea : OsuTestCase
|
||||
{
|
||||
private RulesetInfo catchRuleset;
|
||||
private TestCatcherArea catcherArea;
|
||||
|
||||
@@ -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
|
||||
|
||||
using NUnit.Framework;
|
||||
@@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
public class TestCaseHyperdash : Game.Tests.Visual.TestCasePlayer
|
||||
{
|
||||
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
|
||||
|
||||
using NUnit.Framework;
|
||||
@@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
public class TestCasePerformancePoints : Game.Tests.Visual.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
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using OpenTK;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
@@ -22,17 +22,18 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
private readonly CatcherArea catcherArea;
|
||||
|
||||
public CatchPlayfield(BeatmapDifficulty difficulty)
|
||||
: base(Axes.Y)
|
||||
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
|
||||
: base(ScrollingDirection.Down, BASE_WIDTH)
|
||||
{
|
||||
Container explodingFruitContainer;
|
||||
|
||||
Reversed.Value = true;
|
||||
|
||||
Anchor = Anchor.TopCentre;
|
||||
Origin = Anchor.TopCentre;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
ScaledContent.Anchor = Anchor.BottomLeft;
|
||||
ScaledContent.Origin = Anchor.BottomLeft;
|
||||
|
||||
ScaledContent.AddRange(new Drawable[]
|
||||
{
|
||||
content = new Container<Drawable>
|
||||
{
|
||||
@@ -44,11 +45,12 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
},
|
||||
catcherArea = new CatcherArea(difficulty)
|
||||
{
|
||||
GetVisualRepresentation = getVisualRepresentation,
|
||||
ExplodingFruitTarget = explodingFruitContainer,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj);
|
||||
@@ -56,6 +58,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
public override void Add(DrawableHitObject h)
|
||||
{
|
||||
h.Depth = (float)h.HitObject.StartTime;
|
||||
h.OnJudgement += onJudgement;
|
||||
|
||||
base.Add(h);
|
||||
|
||||
@@ -63,18 +66,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
fruit.CheckPosition = CheckIfWeCanCatch;
|
||||
}
|
||||
|
||||
public override void OnJudgement(DrawableHitObject judgedObject, Judgement 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);
|
||||
}
|
||||
}
|
||||
private void onJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
using osu.Framework.Input;
|
||||
@@ -6,10 +6,14 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||
using osu.Game.Rulesets.Catch.Replays;
|
||||
using osu.Game.Rulesets.Catch.Scoring;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
@@ -22,23 +26,31 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
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 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);
|
||||
|
||||
protected override DrawableHitObject<CatchHitObject> GetVisualRepresentation(CatchHitObject h)
|
||||
{
|
||||
var fruit = h as Fruit;
|
||||
if (fruit != null)
|
||||
return new DrawableFruit(fruit);
|
||||
|
||||
var stream = h as JuiceStream;
|
||||
if (stream != null)
|
||||
return new DrawableJuiceStream(stream);
|
||||
switch (h)
|
||||
{
|
||||
case Fruit fruit:
|
||||
return new DrawableFruit(fruit);
|
||||
case JuiceStream stream:
|
||||
return new DrawableJuiceStream(stream, GetVisualRepresentation);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
using System;
|
||||
@@ -12,18 +12,23 @@ using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Beatmaps;
|
||||
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 OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
public class CatcherArea : Container
|
||||
public class CatcherArea : Container, IKeyBindingHandler<CatchAction>
|
||||
{
|
||||
public const float CATCHER_SIZE = 172;
|
||||
|
||||
protected readonly Catcher MovableCatcher;
|
||||
|
||||
public Func<CatchHitObject, DrawableHitObject<CatchHitObject>> GetVisualRepresentation;
|
||||
|
||||
public Container ExplodingFruitTarget
|
||||
{
|
||||
set { MovableCatcher.ExplodingFruitTarget = value; }
|
||||
@@ -39,19 +44,60 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
};
|
||||
}
|
||||
|
||||
public void Add(DrawableHitObject fruit, Vector2 absolutePosition)
|
||||
private DrawableCatchHitObject lastPlateableFruit;
|
||||
|
||||
public void OnJudgement(DrawableCatchHitObject fruit, Judgement judgement)
|
||||
{
|
||||
fruit.RelativePositionAxes = Axes.None;
|
||||
fruit.Position = new Vector2(MovableCatcher.ToLocalSpace(absolutePosition).X - MovableCatcher.DrawSize.X / 2, 0);
|
||||
if (judgement.IsHit && fruit.CanBePlated)
|
||||
{
|
||||
var caughtFruit = (DrawableCatchHitObject)GetVisualRepresentation?.Invoke(fruit.HitObject);
|
||||
|
||||
fruit.Anchor = Anchor.TopCentre;
|
||||
fruit.Origin = Anchor.BottomCentre;
|
||||
fruit.Scale *= 0.7f;
|
||||
fruit.LifetimeEnd = double.MaxValue;
|
||||
if (caughtFruit == null) return;
|
||||
|
||||
MovableCatcher.Add(fruit);
|
||||
caughtFruit.AccentColour = fruit.AccentColour;
|
||||
caughtFruit.RelativePositionAxes = Axes.None;
|
||||
caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(fruit.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0);
|
||||
|
||||
caughtFruit.Anchor = Anchor.TopCentre;
|
||||
caughtFruit.Origin = Anchor.Centre;
|
||||
caughtFruit.Scale *= 0.7f;
|
||||
caughtFruit.LifetimeEnd = double.MaxValue;
|
||||
|
||||
MovableCatcher.Add(caughtFruit);
|
||||
|
||||
lastPlateableFruit = caughtFruit;
|
||||
}
|
||||
|
||||
if (fruit.HitObject.LastInCombo)
|
||||
{
|
||||
if (judgement.IsHit)
|
||||
{
|
||||
// this is required to make this run after the last caught fruit runs UpdateState at least once.
|
||||
// TODO: find a better alternative
|
||||
if (lastPlateableFruit.IsLoaded)
|
||||
MovableCatcher.Explode();
|
||||
else
|
||||
lastPlateableFruit.OnLoadComplete = _ => { MovableCatcher.Explode(); };
|
||||
}
|
||||
else
|
||||
MovableCatcher.Drop();
|
||||
}
|
||||
}
|
||||
|
||||
public bool OnPressed(CatchAction action)
|
||||
{
|
||||
if (action != CatchAction.PositionUpdate) return false;
|
||||
|
||||
CatchFramedReplayInputHandler.CatchReplayState state = (CatchFramedReplayInputHandler.CatchReplayState)GetContainingInputManager().CurrentState;
|
||||
|
||||
if (state.CatcherX.HasValue)
|
||||
MovableCatcher.X = state.CatcherX.Value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnReleased(CatchAction action) => false;
|
||||
|
||||
public bool AttemptCatch(CatchHitObject obj) => MovableCatcher.AttemptCatch(obj);
|
||||
|
||||
public class Catcher : Container, IKeyBindingHandler<CatchAction>
|
||||
@@ -84,12 +130,12 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
createCatcherSprite(),
|
||||
caughtFruit = new Container<DrawableHitObject>
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
}
|
||||
},
|
||||
createCatcherSprite(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -167,20 +213,23 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
/// <param name="fruit">The fruit that was caught.</param>
|
||||
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);
|
||||
fruit.Y -= RNG.Next(0, 5);
|
||||
float diff = (ourRadius + theirRadius) / allowance;
|
||||
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);
|
||||
|
||||
var catchObject = (CatchHitObject)fruit.HitObject;
|
||||
|
||||
if (catchObject.LastInCombo)
|
||||
explode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -190,15 +239,15 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
/// <returns>Whether the catch is possible.</returns>
|
||||
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.
|
||||
var catchObjectPosition = fruit.X * CatchPlayfield.BASE_WIDTH;
|
||||
var catcherPosition = Position.X * CatchPlayfield.BASE_WIDTH;
|
||||
|
||||
var validCatch =
|
||||
catchObjectPosition >= catcherPosition - relative_catcher_width / 2 &&
|
||||
catchObjectPosition <= catcherPosition + relative_catcher_width / 2;
|
||||
catchObjectPosition >= catcherPosition - halfCatcherWidth &&
|
||||
catchObjectPosition <= catcherPosition + halfCatcherWidth;
|
||||
|
||||
if (validCatch && fruit.HyperDash)
|
||||
{
|
||||
@@ -309,7 +358,35 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * BASE_SPEED * dashModifier, 0, 1);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
<HintPath>$(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
|
||||
<HintPath>$(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll</HintPath>
|
||||
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4">
|
||||
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.3.0.11\lib\net45\OpenTK.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
@@ -49,11 +49,28 @@
|
||||
<Compile Include="Beatmaps\CatchBeatmapProcessor.cs" />
|
||||
<Compile Include="CatchDifficultyCalculator.cs" />
|
||||
<Compile Include="CatchInputManager.cs" />
|
||||
<Compile Include="Mods\CatchModDaycore.cs" />
|
||||
<Compile Include="Mods\CatchModDoubleTime.cs" />
|
||||
<Compile Include="Mods\CatchModEasy.cs" />
|
||||
<Compile Include="Mods\CatchModFlashlight.cs" />
|
||||
<Compile Include="Mods\CatchModHalfTime.cs" />
|
||||
<Compile Include="Mods\CatchModHardRock.cs" />
|
||||
<Compile Include="Mods\CatchModHidden.cs" />
|
||||
<Compile Include="Mods\CatchModNightcore.cs" />
|
||||
<Compile Include="Mods\CatchModPerfect.cs" />
|
||||
<Compile Include="Mods\CatchModRelax.cs" />
|
||||
<Compile Include="Mods\CatchModSuddenDeath.cs" />
|
||||
<Compile Include="Mods\CatchModAutoplay.cs" />
|
||||
<Compile Include="Objects\BananaShower.cs" />
|
||||
<Compile Include="Objects\Drawable\DrawableBananaShower.cs" />
|
||||
<Compile Include="Objects\Drawable\DrawableCatchHitObject.cs" />
|
||||
<Compile Include="Objects\Drawable\DrawableDroplet.cs" />
|
||||
<Compile Include="Objects\Drawable\DrawableJuiceStream.cs" />
|
||||
<Compile Include="Objects\Drawable\Pieces\Pulp.cs" />
|
||||
<Compile Include="Objects\JuiceStream.cs" />
|
||||
<Compile Include="Replays\CatchAutoGenerator.cs" />
|
||||
<Compile Include="Replays\CatchFramedReplayInputHandler.cs" />
|
||||
<Compile Include="Replays\CatchReplayFrame.cs" />
|
||||
<Compile Include="Scoring\CatchScoreProcessor.cs" />
|
||||
<Compile Include="Judgements\CatchJudgement.cs" />
|
||||
<Compile Include="Objects\CatchHitObject.cs" />
|
||||
@@ -62,8 +79,10 @@
|
||||
<Compile Include="Objects\Fruit.cs" />
|
||||
<Compile Include="Objects\TinyDroplet.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Tests\TestCaseBananaShower.cs" />
|
||||
<Compile Include="Tests\TestCaseCatcherArea.cs" />
|
||||
<Compile Include="Tests\TestCaseCatchStacker.cs" />
|
||||
<Compile Include="Tests\TestCaseFruitObjects.cs" />
|
||||
<Compile Include="Tests\TestCasePerformancePoints.cs" />
|
||||
<Compile Include="Tests\TestCaseCatchPlayer.cs" />
|
||||
<Compile Include="Tests\TestCaseHyperdash.cs" />
|
||||
@@ -71,7 +90,7 @@
|
||||
<Compile Include="UI\CatchRulesetContainer.cs" />
|
||||
<Compile Include="UI\CatchPlayfield.cs" />
|
||||
<Compile Include="CatchRuleset.cs" />
|
||||
<Compile Include="Mods\CatchMod.cs" />
|
||||
<Compile Include="Mods\CatchModNoFail.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
@@ -90,6 +109,9 @@
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="NUnit" version="3.8.1" targetFramework="net461" />
|
||||
<package id="OpenTK" version="3.0.0-git00009" targetFramework="net461" />
|
||||
<package id="ppy.OpenTK" version="3.0.11" targetFramework="net461" />
|
||||
</packages>
|
||||
@@ -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 readonly 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="initialStage">The initial stage.</param>
|
||||
public ManiaBeatmap(StageDefinition initialStage)
|
||||
{
|
||||
Stages.Add(initialStage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
@@ -24,25 +25,39 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
|
||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
||||
|
||||
public int TargetColumns;
|
||||
public readonly bool IsForCurrentRuleset;
|
||||
|
||||
private Pattern lastPattern = new Pattern();
|
||||
private FastRandom random;
|
||||
private Beatmap beatmap;
|
||||
|
||||
private readonly int availableColumns;
|
||||
private readonly bool isForCurrentRuleset;
|
||||
private ManiaBeatmap beatmap;
|
||||
|
||||
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;
|
||||
this.availableColumns = availableColumns;
|
||||
var roundedCircleSize = Math.Round(original.BeatmapInfo.BaseDifficulty.CircleSize);
|
||||
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)
|
||||
{
|
||||
beatmap = original;
|
||||
|
||||
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);
|
||||
@@ -51,6 +66,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
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)
|
||||
{
|
||||
var maniaOriginal = original as ManiaHitObject;
|
||||
@@ -60,7 +77,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
yield break;
|
||||
}
|
||||
|
||||
var objects = isForCurrentRuleset ? generateSpecific(original) : generateConverted(original);
|
||||
var objects = IsForCurrentRuleset ? generateSpecific(original) : generateConverted(original);
|
||||
|
||||
if (objects == null)
|
||||
yield break;
|
||||
@@ -96,7 +113,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
/// <returns>The hit objects generated.</returns>
|
||||
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();
|
||||
lastPattern = newPattern;
|
||||
@@ -120,14 +137,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
Patterns.PatternGenerator conversion = null;
|
||||
|
||||
if (distanceData != null)
|
||||
conversion = new DistanceObjectPatternGenerator(random, original, beatmap, availableColumns, lastPattern);
|
||||
conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern);
|
||||
else if (endTimeData != null)
|
||||
conversion = new EndTimeObjectPatternGenerator(random, original, beatmap, availableColumns);
|
||||
conversion = new EndTimeObjectPatternGenerator(random, original, beatmap);
|
||||
else if (positionData != null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -149,8 +166,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
/// </summary>
|
||||
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
|
||||
{
|
||||
public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
||||
: base(random, hitObject, beatmap, availableColumns, previousPattern)
|
||||
public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||
: base(random, hitObject, beatmap, previousPattern)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -192,7 +209,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
/// </summary>
|
||||
/// <param name="time">The time to retrieve the sample info list from.</param>
|
||||
/// <returns></returns>
|
||||
private SampleInfoList sampleInfoListAt(double time)
|
||||
private List<SampleInfo> sampleInfoListAt(double time)
|
||||
{
|
||||
var curveData = HitObject as IHasCurve;
|
||||
|
||||
|
||||
+34
-34
@@ -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
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.MathUtils;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
@@ -29,8 +29,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
private PatternType convertType;
|
||||
|
||||
public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
||||
: base(random, hitObject, beatmap, availableColumns, previousPattern)
|
||||
public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||
: base(random, hitObject, beatmap, previousPattern)
|
||||
{
|
||||
convertType = PatternType.None;
|
||||
if (Beatmap.ControlPointInfo.EffectPointAt(hitObject.StartTime).KiaiMode)
|
||||
@@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
if (duration >= 4000)
|
||||
return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0);
|
||||
|
||||
if (segmentDuration > 400 && repeatCount < AvailableColumns - 1 - RandomStart)
|
||||
if (segmentDuration > 400 && repeatCount < TotalColumns - 1 - RandomStart)
|
||||
return generateTiledHoldNotes(HitObject.StartTime);
|
||||
|
||||
return generateHoldAndNormalNotes(HitObject.StartTime);
|
||||
@@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
if (segmentDuration <= 110)
|
||||
{
|
||||
if (PreviousPattern.ColumnWithObjects < AvailableColumns)
|
||||
if (PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||
convertType |= PatternType.ForceNotStack;
|
||||
else
|
||||
convertType &= ~PatternType.ForceNotStack;
|
||||
@@ -134,12 +134,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
var pattern = new Pattern();
|
||||
|
||||
int usableColumns = AvailableColumns - RandomStart - PreviousPattern.ColumnWithObjects;
|
||||
int nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
int usableColumns = TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects;
|
||||
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
for (int i = 0; i < noteCount - usableColumns; i++)
|
||||
{
|
||||
while (pattern.ColumnHasObject(nextColumn))
|
||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
||||
}
|
||||
|
||||
@@ -171,10 +171,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
var pattern = new Pattern();
|
||||
|
||||
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))
|
||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
}
|
||||
|
||||
int lastColumn = nextColumn;
|
||||
@@ -182,7 +182,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
{
|
||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||
while (nextColumn == lastColumn)
|
||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
|
||||
lastColumn = nextColumn;
|
||||
startTime += segmentDuration;
|
||||
@@ -220,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
|
||||
if (increasing)
|
||||
{
|
||||
if (column >= AvailableColumns - 1)
|
||||
if (column >= TotalColumns - 1)
|
||||
{
|
||||
increasing = false;
|
||||
column--;
|
||||
@@ -258,8 +258,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
var pattern = new Pattern();
|
||||
|
||||
bool legacy = AvailableColumns >= 4 && AvailableColumns <= 8;
|
||||
int interval = Random.Next(1, AvailableColumns - (legacy ? 1 : 0));
|
||||
bool legacy = TotalColumns >= 4 && TotalColumns <= 8;
|
||||
int interval = Random.Next(1, TotalColumns - (legacy ? 1 : 0));
|
||||
|
||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||
for (int i = 0; i <= repeatCount; i++)
|
||||
@@ -267,15 +267,15 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||
|
||||
nextColumn += interval;
|
||||
if (nextColumn >= AvailableColumns - RandomStart)
|
||||
nextColumn = nextColumn - AvailableColumns - RandomStart + (legacy ? 1 : 0);
|
||||
if (nextColumn >= TotalColumns - RandomStart)
|
||||
nextColumn = nextColumn - TotalColumns - RandomStart + (legacy ? 1 : 0);
|
||||
nextColumn += RandomStart;
|
||||
|
||||
// If we're in 2K, let's not add many consecutive doubles
|
||||
if (AvailableColumns > 2)
|
||||
if (TotalColumns > 2)
|
||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||
|
||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
startTime += segmentDuration;
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
// □ - □ □
|
||||
// ■ - ■ ■
|
||||
|
||||
switch (AvailableColumns)
|
||||
switch (TotalColumns)
|
||||
{
|
||||
case 2:
|
||||
p2 = 0;
|
||||
@@ -321,7 +321,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
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;
|
||||
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample);
|
||||
@@ -350,19 +350,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
var pattern = new Pattern();
|
||||
|
||||
int columnRepeat = Math.Min(repeatCount, AvailableColumns);
|
||||
int columnRepeat = Math.Min(repeatCount, TotalColumns);
|
||||
|
||||
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))
|
||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
}
|
||||
|
||||
for (int i = 0; i < columnRepeat; i++)
|
||||
{
|
||||
while (pattern.ColumnHasObject(nextColumn))
|
||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
|
||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
||||
startTime += segmentDuration;
|
||||
@@ -387,10 +387,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
var pattern = new Pattern();
|
||||
|
||||
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))
|
||||
holdColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
holdColumn = Random.Next(RandomStart, TotalColumns);
|
||||
}
|
||||
|
||||
// Create the hold note
|
||||
@@ -400,13 +400,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
if (ConversionDifficulty > 6.5)
|
||||
noteCount = GetRandomNoteCount(0.63, 0);
|
||||
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)
|
||||
noteCount = GetRandomNoteCount(AvailableColumns < 6 ? 0 : 0.24, 0);
|
||||
noteCount = Math.Min(AvailableColumns - 1, noteCount);
|
||||
noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0 : 0.24, 0);
|
||||
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);
|
||||
int nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
|
||||
var rowPattern = new Pattern();
|
||||
for (int i = 0; i <= repeatCount; i++)
|
||||
@@ -416,7 +416,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
for (int j = 0; j < noteCount; j++)
|
||||
{
|
||||
while (rowPattern.ColumnHasObject(nextColumn) || nextColumn == holdColumn)
|
||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
addToPattern(rowPattern, nextColumn, startTime, startTime);
|
||||
}
|
||||
}
|
||||
@@ -435,7 +435,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
/// </summary>
|
||||
/// <param name="time">The time to retrieve the sample info list from.</param>
|
||||
/// <returns></returns>
|
||||
private SampleInfoList sampleInfoListAt(double time)
|
||||
private List<SampleInfo> sampleInfoListAt(double time)
|
||||
{
|
||||
var curveData = HitObject as IHasCurve;
|
||||
|
||||
|
||||
@@ -1,7 +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
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Rulesets.Mania.MathUtils;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
@@ -15,8 +15,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
{
|
||||
private readonly double endTime;
|
||||
|
||||
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns)
|
||||
: base(random, hitObject, beatmap, availableColumns, new Pattern())
|
||||
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap)
|
||||
: base(random, hitObject, beatmap, new Pattern())
|
||||
{
|
||||
var endtimeData = HitObject as IHasEndTime;
|
||||
|
||||
@@ -29,14 +29,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
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)
|
||||
addToPattern(pattern, 0, generateHold);
|
||||
else
|
||||
addToPattern(pattern, getNextRandomColumn(RandomStart), generateHold);
|
||||
}
|
||||
else if (AvailableColumns > 0)
|
||||
else if (TotalColumns > 0)
|
||||
addToPattern(pattern, getNextRandomColumn(0), generateHold);
|
||||
|
||||
return pattern;
|
||||
@@ -49,10 +49,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
/// <returns>A random column after <paramref name="start"/>.</returns>
|
||||
private int getNextRandomColumn(int start)
|
||||
{
|
||||
int nextColumn = Random.Next(start, AvailableColumns);
|
||||
int nextColumn = Random.Next(start, TotalColumns);
|
||||
|
||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
||||
nextColumn = Random.Next(start, AvailableColumns);
|
||||
nextColumn = Random.Next(start, TotalColumns);
|
||||
|
||||
return nextColumn;
|
||||
}
|
||||
@@ -76,10 +76,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
Duration = endTime - HitObject.StartTime
|
||||
};
|
||||
|
||||
hold.Head.Samples.Add(new SampleInfo
|
||||
{
|
||||
Name = SampleInfo.HIT_NORMAL
|
||||
});
|
||||
if (hold.Head.Samples == null)
|
||||
hold.Head.Samples = new List<SampleInfo>();
|
||||
|
||||
hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL });
|
||||
|
||||
hold.Tail.Samples = HitObject.Samples;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenTK;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Mania.MathUtils;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
@@ -20,8 +19,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
private readonly PatternType convertType;
|
||||
|
||||
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair)
|
||||
: base(random, hitObject, beatmap, availableColumns, previousPattern)
|
||||
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair)
|
||||
: base(random, hitObject, beatmap, previousPattern)
|
||||
{
|
||||
if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime));
|
||||
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
|
||||
var pattern = new Pattern();
|
||||
|
||||
for (int i = RandomStart; i < AvailableColumns; i++)
|
||||
for (int i = RandomStart; i < TotalColumns; i++)
|
||||
if (PreviousPattern.ColumnHasObject(i))
|
||||
addToPattern(pattern, RandomStart + AvailableColumns - i - 1);
|
||||
addToPattern(pattern, RandomStart + TotalColumns - i - 1);
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1
|
||||
// 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
|
||||
&& (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)
|
||||
var pattern = new Pattern();
|
||||
|
||||
int column = RandomStart + AvailableColumns - lastColumn - 1;
|
||||
int column = RandomStart + TotalColumns - lastColumn - 1;
|
||||
addToPattern(pattern, column);
|
||||
|
||||
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
|
||||
var pattern = new Pattern();
|
||||
|
||||
for (int i = RandomStart; i < AvailableColumns; i++)
|
||||
for (int i = RandomStart; i < TotalColumns; i++)
|
||||
if (PreviousPattern.ColumnHasObject(i))
|
||||
addToPattern(pattern, i);
|
||||
|
||||
@@ -128,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
var pattern = new Pattern();
|
||||
|
||||
int targetColumn = lastColumn + 1;
|
||||
if (targetColumn == AvailableColumns)
|
||||
if (targetColumn == TotalColumns)
|
||||
{
|
||||
targetColumn = RandomStart;
|
||||
StairType = PatternType.ReverseStair;
|
||||
@@ -146,7 +145,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
int targetColumn = lastColumn - 1;
|
||||
if (targetColumn == RandomStart - 1)
|
||||
{
|
||||
targetColumn = AvailableColumns - 1;
|
||||
targetColumn = TotalColumns - 1;
|
||||
StairType = PatternType.Stair;
|
||||
}
|
||||
|
||||
@@ -206,7 +205,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
bool allowStacking = (convertType & PatternType.ForceNotStack) == 0;
|
||||
|
||||
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);
|
||||
for (int i = 0; i < noteCount; i++)
|
||||
@@ -216,11 +215,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
if ((convertType & PatternType.Gathered) > 0)
|
||||
{
|
||||
nextColumn++;
|
||||
if (nextColumn == AvailableColumns)
|
||||
if (nextColumn == TotalColumns)
|
||||
nextColumn = RandomStart;
|
||||
}
|
||||
else
|
||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
||||
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||
}
|
||||
|
||||
addToPattern(pattern, nextColumn);
|
||||
@@ -268,7 +267,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
bool 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);
|
||||
for (int i = 0; i < noteCount; i++)
|
||||
{
|
||||
@@ -278,11 +277,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
// Add normal note
|
||||
addToPattern(pattern, nextColumn);
|
||||
// Add mirrored note
|
||||
addToPattern(pattern, RandomStart + AvailableColumns - nextColumn - 1);
|
||||
addToPattern(pattern, RandomStart + TotalColumns - nextColumn - 1);
|
||||
}
|
||||
|
||||
if (addToCentre)
|
||||
addToPattern(pattern, AvailableColumns / 2);
|
||||
addToPattern(pattern, TotalColumns / 2);
|
||||
|
||||
if (RandomStart > 0 && hasSpecialColumn)
|
||||
addToPattern(pattern, 0);
|
||||
@@ -300,7 +299,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
/// <returns>The amount of notes to be generated.</returns>
|
||||
private int getRandomNoteCount(double p2, double p3, double p4, double p5)
|
||||
{
|
||||
switch (AvailableColumns)
|
||||
switch (TotalColumns)
|
||||
{
|
||||
case 2:
|
||||
p2 = 0;
|
||||
@@ -348,7 +347,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
if ((convertType & PatternType.ForceNotStack) > 0)
|
||||
return getRandomNoteCount(p2 / 2, p2, (p2 + p3) / 2, p3);
|
||||
|
||||
switch (AvailableColumns)
|
||||
switch (TotalColumns)
|
||||
{
|
||||
case 2:
|
||||
centreProbability = 0;
|
||||
@@ -379,7 +378,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
double centreVal = Random.NextDouble();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
using System;
|
||||
@@ -25,16 +25,15 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
/// </summary>
|
||||
protected readonly FastRandom Random;
|
||||
|
||||
protected PatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
||||
: base(hitObject, beatmap, availableColumns, previousPattern)
|
||||
protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||
: base(hitObject, beatmap, previousPattern)
|
||||
{
|
||||
if (random == null) throw new ArgumentNullException(nameof(random));
|
||||
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
||||
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
|
||||
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
||||
|
||||
Random = random;
|
||||
RandomStart = AvailableColumns == 8 ? 1 : 0;
|
||||
RandomStart = TotalColumns == 8 ? 1 : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -45,14 +44,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
/// <returns>The column.</returns>
|
||||
protected int GetColumn(float position, bool allowSpecial = false)
|
||||
{
|
||||
if (allowSpecial && AvailableColumns == 8)
|
||||
if (allowSpecial && TotalColumns == 8)
|
||||
{
|
||||
const float local_x_divisor = 512f / 7;
|
||||
return MathHelper.Clamp((int)Math.Floor(position / local_x_divisor), 0, 6) + 1;
|
||||
}
|
||||
|
||||
float localXDivisor = 512f / AvailableColumns;
|
||||
return MathHelper.Clamp((int)Math.Floor(position / localXDivisor), 0, AvailableColumns - 1);
|
||||
float localXDivisor = 512f / TotalColumns;
|
||||
return MathHelper.Clamp((int)Math.Floor(position / localXDivisor), 0, TotalColumns - 1);
|
||||
}
|
||||
|
||||
/// <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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
using System;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
||||
@@ -12,11 +11,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
||||
/// </summary>
|
||||
internal abstract class PatternGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// The number of columns available to create the pattern.
|
||||
/// </summary>
|
||||
protected readonly int AvailableColumns;
|
||||
|
||||
/// <summary>
|
||||
/// The last pattern.
|
||||
/// </summary>
|
||||
@@ -30,19 +24,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
||||
/// <summary>
|
||||
/// The beatmap which <see cref="HitObject"/> is a part of.
|
||||
/// </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 (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
||||
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
|
||||
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
||||
|
||||
HitObject = hitObject;
|
||||
Beatmap = beatmap;
|
||||
AvailableColumns = availableColumns;
|
||||
PreviousPattern = previousPattern;
|
||||
|
||||
TotalColumns = Beatmap.TotalColumns;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,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
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Judgements
|
||||
{
|
||||
|
||||
@@ -1,7 +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
|
||||
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Judgements
|
||||
{
|
||||
@@ -24,4 +24,4 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +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
|
||||
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Judgements
|
||||
{
|
||||
@@ -11,4 +11,4 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
||||
|
||||
protected override int NumericResultFor(HitResult result) => 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,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
|
||||
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.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
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
@@ -18,6 +17,6 @@ namespace osu.Game.Rulesets.Mania
|
||||
|
||||
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
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
@@ -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
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
@@ -95,7 +95,6 @@ namespace osu.Game.Rulesets.Mania
|
||||
new ModCinema(),
|
||||
},
|
||||
},
|
||||
new ManiaModGravity()
|
||||
};
|
||||
|
||||
default:
|
||||
@@ -105,13 +104,15 @@ namespace osu.Game.Rulesets.Mania
|
||||
|
||||
public override string Description => "osu!mania";
|
||||
|
||||
public override string ShortName => "mania";
|
||||
|
||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new ManiaDifficultyCalculator(beatmap);
|
||||
|
||||
public override int LegacyID => 3;
|
||||
|
||||
public ManiaRuleset(RulesetInfo rulesetInfo)
|
||||
public ManiaRuleset(RulesetInfo rulesetInfo = null)
|
||||
: 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
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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,185 +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
|
||||
{
|
||||
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(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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) };
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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) };
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user