1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-15 04:12:57 +08:00

Merge pull request #6 from ppy/master

Sync fork up to date
This commit is contained in:
Nathan Alo 2019-06-03 13:41:31 +08:00 committed by GitHub
commit 78f8157e2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
613 changed files with 8513 additions and 3470 deletions

View File

@ -1,6 +1,6 @@
clone_depth: 1
version: '{branch}-{build}'
image: Visual Studio 2017
image: Previous Visual Studio 2017
test: off
install:
- cmd: git submodule update --init --recursive --depth=5

View File

@ -1,5 +1,5 @@
#addin "nuget:?package=CodeFileSanity&version=0.0.21"
#addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.3.4"
#addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2019.1.1"
#tool "nuget:?package=NVika.MSBuild&version=1.0.1"
var nVikaToolPath = GetFiles("./tools/NVika.MSBuild.*/tools/NVika.exe").First();

View File

@ -35,7 +35,7 @@ platform :ios do
changelog.gsub!('$BUILD_ID', options[:build])
pilot(
wait_processing_interval: 900,
wait_processing_interval: 1800,
changelog: changelog,
ipa: './osu.iOS/bin/iPhone/Release/osu.iOS.ipa'
)

View File

@ -77,6 +77,7 @@ namespace osu.Desktop
if (versionManager != null)
versionManager.State = Visibility.Visible;
break;
default:
if (versionManager != null)
versionManager.State = Visibility.Hidden;
@ -87,6 +88,7 @@ namespace osu.Desktop
public override void SetHost(GameHost host)
{
base.SetHost(host);
if (host.Window is DesktopGameWindow desktopWindow)
{
desktopWindow.CursorState |= CursorState.Hidden;

View File

@ -1,13 +1,11 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Platform;
using osu.Game;
using osu.Game.Configuration;
using osu.Game.Graphics;
@ -25,15 +23,13 @@ namespace osu.Desktop.Overlays
private OsuConfigManager config;
private OsuGameBase game;
private NotificationOverlay notificationOverlay;
private GameHost host;
[BackgroundDependencyLoader]
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config, GameHost host)
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config)
{
notificationOverlay = notification;
this.config = config;
this.game = game;
this.host = host;
AutoSizeAxes = Axes.Both;
Anchor = Anchor.BottomCentre;
@ -95,33 +91,38 @@ namespace osu.Desktop.Overlays
var version = game.Version;
var lastVersion = config.Get<string>(OsuSetting.Version);
if (game.IsDeployedBuild && version != lastVersion)
{
config.Set(OsuSetting.Version, version);
// only show a notification if we've previously saved a version to the config file (ie. not the first run).
if (!string.IsNullOrEmpty(lastVersion))
notificationOverlay.Post(new UpdateCompleteNotification(version, host.OpenUrlExternally));
notificationOverlay.Post(new UpdateCompleteNotification(version));
}
}
private class UpdateCompleteNotification : SimpleNotification
{
public UpdateCompleteNotification(string version, Action<string> openUrl = null)
private readonly string version;
public UpdateCompleteNotification(string version)
{
this.version = version;
Text = $"You are now running osu!lazer {version}.\nClick to see what's new!";
Icon = FontAwesome.Solid.CheckSquare;
Activated = delegate
{
openUrl?.Invoke($"https://osu.ppy.sh/home/changelog/lazer/{version}");
return true;
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, ChangelogOverlay changelog)
{
Icon = FontAwesome.Solid.CheckSquare;
IconBackgound.Colour = colours.BlueDark;
Activated = delegate
{
changelog.ShowBuild("lazer", version);
return true;
};
}
}

View File

@ -31,6 +31,7 @@ namespace osu.Desktop
var importer = new ArchiveImportIPCChannel(host);
// Restore the cwd so relative paths given at the command line work correctly
Directory.SetCurrentDirectory(cwd);
foreach (var file in args)
{
Console.WriteLine(@"Importing {0}", file);

View File

@ -78,6 +78,7 @@ namespace osu.Desktop.Updater
case RuntimeInfo.Platform.Windows:
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".exe"));
break;
case RuntimeInfo.Platform.MacOsx:
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".app.zip"));
break;

View File

@ -2,8 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@ -169,23 +167,19 @@ namespace osu.Desktop.Updater
private class SquirrelLogger : Splat.ILogger, IDisposable
{
private readonly string path;
private readonly object locker = new object();
public LogLevel Level { get; set; } = LogLevel.Info;
public SquirrelLogger()
{
var file = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "SquirrelSetupUpdater.log");
if (File.Exists(file)) File.Delete(file);
path = file;
}
private Logger logger;
public void Write(string message, LogLevel logLevel)
{
if (logLevel < Level)
return;
lock (locker) File.AppendAllText(path, message + "\r\n");
if (logger == null)
logger = Logger.GetLogger("updater");
logger.Add(message);
}
public void Dispose()

View File

@ -26,9 +26,9 @@
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="System.IO.Packaging" Version="4.5.0" />
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.3" />
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.4" />
</ItemGroup>
<ItemGroup Label="Resources">
<EmbeddedResource Include="lazer.ico" />

View File

@ -36,11 +36,13 @@ namespace osu.Game.Rulesets.Catch.Tests
yield return new ConvertValue((CatchHitObject)nested);
break;
case BananaShower shower:
foreach (var nested in shower.NestedHitObjects)
yield return new ConvertValue((CatchHitObject)nested);
break;
default:
yield return new ConvertValue((CatchHitObject)hitObject);

View File

@ -13,9 +13,9 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests
{
public class TestCaseAutoJuiceStream : PlayerTestCase
public class TestSceneAutoJuiceStream : PlayerTestScene
{
public TestCaseAutoJuiceStream()
public TestSceneAutoJuiceStream()
: base(new CatchRuleset())
{
}
@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.Tests
protected override Player CreatePlayer(Ruleset ruleset)
{
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
return base.CreatePlayer(ruleset);
}
}

View File

@ -13,7 +13,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseBananaShower : PlayerTestCase
public class TestSceneBananaShower : PlayerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(DrawableCatchRuleset),
};
public TestCaseBananaShower()
public TestSceneBananaShower()
: base(new CatchRuleset())
{
}

View File

@ -7,9 +7,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseCatchPlayer : PlayerTestCase
public class TestSceneCatchPlayer : PlayerTestScene
{
public TestCaseCatchPlayer()
public TestSceneCatchPlayer()
: base(new CatchRuleset())
{
}

View File

@ -9,9 +9,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseCatchStacker : PlayerTestCase
public class TestSceneCatchStacker : PlayerTestScene
{
public TestCaseCatchStacker()
public TestSceneCatchStacker()
: base(new CatchRuleset())
{
}

View File

@ -13,7 +13,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseCatcherArea : OsuTestCase
public class TestSceneCatcherArea : OsuTestScene
{
private RulesetInfo catchRuleset;
private TestCatcherArea catcherArea;
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(CatcherArea),
};
public TestCaseCatcherArea()
public TestSceneCatcherArea()
{
AddSliderStep<float>("CircleSize", 0, 8, 5, createCatcher);
AddToggleStep("Hyperdash", t => catcherArea.ToggleHyperDash(t));

View File

@ -15,7 +15,7 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseFruitObjects : OsuTestCase
public class TestSceneFruitObjects : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(Pulp),
};
public TestCaseFruitObjects()
public TestSceneFruitObjects()
{
Add(new GridContainer
{

View File

@ -10,9 +10,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseHyperDash : PlayerTestCase
public class TestSceneHyperDash : PlayerTestScene
{
public TestCaseHyperDash()
public TestSceneHyperDash()
: base(new CatchRuleset())
{
}

View File

@ -2,8 +2,8 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup>

View File

@ -31,6 +31,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
initialiseHyperDash((List<CatchHitObject>)Beatmap.HitObjects);
int index = 0;
foreach (var obj in Beatmap.HitObjects.OfType<CatchHitObject>())
{
obj.IndexInBeatmap = index++;
@ -58,6 +59,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
}
break;
case JuiceStream juiceStream:
foreach (var nested in juiceStream.NestedHitObjects)
{
@ -103,6 +105,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
double timeToNext = nextObject.StartTime - currentObject.StartTime - 1000f / 60f / 4; // 1/4th of a frame of grace time, taken from osu-stable
double distanceToNext = Math.Abs(nextObject.X - currentObject.X) - (lastDirection == thisDirection ? lastExcess : halfCatcherWidth);
float distanceToHyper = (float)(timeToNext * CatcherArea.Catcher.BASE_SPEED - distanceToNext);
if (distanceToHyper < 0)
{
currentObject.HyperDashTarget = nextObject;

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch
{
public class CatchRuleset : Ruleset
{
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap) => new DrawableCatchRuleset(this, beatmap);
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableCatchRuleset(this, beatmap, mods);
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
@ -87,6 +87,7 @@ namespace osu.Game.Rulesets.Catch
new CatchModNoFail(),
new MultiMod(new CatchModHalfTime(), new CatchModDaycore())
};
case ModType.DifficultyIncrease:
return new Mod[]
{
@ -96,17 +97,20 @@ namespace osu.Game.Rulesets.Catch
new CatchModHidden(),
new CatchModFlashlight(),
};
case ModType.Automation:
return new Mod[]
{
new MultiMod(new CatchModAutoplay(), new ModCinema()),
new CatchModRelax(),
};
case ModType.Fun:
return new Mod[]
{
new MultiMod(new ModWindUp<CatchHitObject>(), new ModWindDown<CatchHitObject>())
};
default:
return new Mod[] { };
}

View File

@ -57,32 +57,20 @@ namespace osu.Game.Rulesets.Catch.Difficulty
CatchHitObject lastObject = null;
foreach (var hitObject in beatmap.HitObjects.OfType<CatchHitObject>())
// In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream.
foreach (var hitObject in beatmap.HitObjects
.SelectMany(obj => obj is JuiceStream stream ? stream.NestedHitObjects : new[] { obj })
.Cast<CatchHitObject>()
.OrderBy(x => x.StartTime))
{
if (lastObject == null)
{
lastObject = hitObject;
// We want to only consider fruits that contribute to the combo.
if (hitObject is BananaShower || hitObject is TinyDroplet)
continue;
}
switch (hitObject)
{
// We want to only consider fruits that contribute to the combo. Droplets are addressed as accuracy and spinners are not relevant for "skill" calculations.
case Fruit fruit:
yield return new CatchDifficultyHitObject(fruit, lastObject, clockRate, halfCatchWidth);
if (lastObject != null)
yield return new CatchDifficultyHitObject(hitObject, lastObject, clockRate, halfCatchWidth);
lastObject = hitObject;
break;
case JuiceStream _:
foreach (var nested in hitObject.NestedHitObjects.OfType<CatchHitObject>().Where(o => !(o is TinyDroplet)))
{
yield return new CatchDifficultyHitObject(nested, lastObject, clockRate, halfCatchWidth);
lastObject = nested;
}
break;
}
lastObject = hitObject;
}
}

View File

@ -16,6 +16,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
case HitResult.Perfect:
return 1100;
}
@ -27,8 +28,9 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
case HitResult.Perfect:
return 8;
return 0.008;
}
}

View File

@ -13,6 +13,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
case HitResult.Perfect:
return 30;
}
@ -23,9 +24,10 @@ namespace osu.Game.Rulesets.Catch.Judgements
switch (result)
{
default:
return 0;
return base.HealthIncreaseFor(result);
case HitResult.Perfect:
return 7;
return 0.007;
}
}
}

View File

@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
case HitResult.Perfect:
return 300;
}
@ -27,9 +28,10 @@ namespace osu.Game.Rulesets.Catch.Judgements
switch (result)
{
default:
return 0;
return -0.02;
case HitResult.Perfect:
return 10.2;
return 0.01;
}
}

View File

@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
case HitResult.Perfect:
return 10;
}
@ -26,8 +27,9 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
case HitResult.Perfect:
return 4;
return 0.004;
}
}
}

View File

@ -84,6 +84,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
case ArmedState.Miss:
this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out).Expire();
break;
case ArmedState.Hit:
this.FadeOut().Expire();
break;

View File

@ -6,6 +6,7 @@ using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.MathUtils;
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
@ -105,6 +106,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
default:
return new Container();
case FruitVisualRepresentation.Raspberry:
return new Container
{
@ -143,6 +145,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
},
}
};
case FruitVisualRepresentation.Pineapple:
return new Container
{
@ -181,6 +184,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
},
}
};
case FruitVisualRepresentation.Pear:
return new Container
{
@ -213,6 +217,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
},
}
};
case FruitVisualRepresentation.Grape:
return new Container
{
@ -245,6 +250,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
},
}
};
case FruitVisualRepresentation.Banana:
return new Container
{
@ -282,19 +288,25 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
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);
}

View File

@ -3,7 +3,7 @@
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osuTK.Graphics;

View File

@ -95,6 +95,7 @@ namespace osu.Game.Rulesets.Catch.Objects
X = X + Path.PositionAt(e.PathProgress).X / CatchPlayfield.BASE_WIDTH,
});
break;
case SliderEventType.Head:
case SliderEventType.Tail:
case SliderEventType.Repeat:

View File

@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Judgements;
@ -27,20 +26,16 @@ namespace osu.Game.Rulesets.Catch.Scoring
hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate;
}
private const double harshness = 0.01;
protected override void ApplyResult(JudgementResult result)
protected override double HealthAdjustmentFactorFor(JudgementResult result)
{
base.ApplyResult(result);
if (result.Type == HitResult.Miss)
switch (result.Type)
{
if (!result.Judgement.IsBonus)
Health.Value -= hpDrainRate * (harshness * 2);
return;
}
case HitResult.Miss:
return hpDrainRate;
Health.Value += Math.Max(result.Judgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
default:
return 10.2 - hpDrainRate; // Award less HP as drain rate is increased
}
}
public override HitWindows CreateHitWindows() => new CatchHitWindows();

View File

@ -292,6 +292,7 @@ namespace osu.Game.Rulesets.Catch.UI
const float hyper_dash_transition_length = 180;
bool previouslyHyperDashing = HyperDashing;
if (modifier <= 1 || X == targetPosition)
{
hyperDashModifier = 1;
@ -325,9 +326,11 @@ namespace osu.Game.Rulesets.Catch.UI
case CatchAction.MoveLeft:
currentDirection--;
return true;
case CatchAction.MoveRight:
currentDirection++;
return true;
case CatchAction.Dash:
Dashing = true;
return true;
@ -343,9 +346,11 @@ namespace osu.Game.Rulesets.Catch.UI
case CatchAction.MoveLeft:
currentDirection++;
return true;
case CatchAction.MoveRight:
currentDirection--;
return true;
case CatchAction.Dash:
Dashing = false;
return true;

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Framework.Input;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
@ -10,6 +11,7 @@ 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.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
@ -23,8 +25,8 @@ namespace osu.Game.Rulesets.Catch.UI
protected override bool UserScrollSpeedAdjustment => false;
public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap)
public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
: base(ruleset, beatmap, mods)
{
Direction.Value = ScrollingDirection.Down;
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
@ -46,14 +48,19 @@ namespace osu.Game.Rulesets.Catch.UI
{
case Banana banana:
return new DrawableBanana(banana);
case Fruit fruit:
return new DrawableFruit(fruit);
case JuiceStream stream:
return new DrawableJuiceStream(stream, CreateDrawableRepresentation);
case BananaShower shower:
return new DrawableBananaShower(shower, CreateDrawableRepresentation);
case TinyDroplet tiny:
return new DrawableTinyDroplet(tiny);
case Droplet droplet:
return new DrawableDroplet(droplet);
}

View File

@ -8,12 +8,12 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
public abstract class ManiaInputTestCase : OsuTestCase
public abstract class ManiaInputTestScene : OsuTestScene
{
private readonly Container<Drawable> content;
protected override Container<Drawable> Content => content ?? base.Content;
protected ManiaInputTestCase(int keys)
protected ManiaInputTestScene(int keys)
{
base.Content.Add(content = new LocalInputManager(keys));
}

View File

@ -1,6 +1,8 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -8,6 +10,7 @@ using osu.Framework.Timing;
using osu.Game.Rulesets.Mania.Edit;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Tests.Visual;
@ -17,11 +20,14 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[Cached(Type = typeof(IManiaHitObjectComposer))]
public abstract class ManiaPlacementBlueprintTestCase : PlacementBlueprintTestCase, IManiaHitObjectComposer
public abstract class ManiaPlacementBlueprintTestScene : PlacementBlueprintTestScene, IManiaHitObjectComposer
{
private readonly Column column;
protected ManiaPlacementBlueprintTestCase()
[Cached(typeof(IReadOnlyList<Mod>))]
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
protected ManiaPlacementBlueprintTestScene()
{
Add(column = new Column(0)
{

View File

@ -13,14 +13,14 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[Cached(Type = typeof(IManiaHitObjectComposer))]
public abstract class ManiaSelectionBlueprintTestCase : SelectionBlueprintTestCase, IManiaHitObjectComposer
public abstract class ManiaSelectionBlueprintTestScene : SelectionBlueprintTestScene, IManiaHitObjectComposer
{
[Cached(Type = typeof(IAdjustableClock))]
private readonly IAdjustableClock clock = new StopwatchClock();
private readonly Column column;
protected ManiaSelectionBlueprintTestCase()
protected ManiaSelectionBlueprintTestScene()
{
Add(column = new Column(0)
{

View File

@ -12,7 +12,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseAutoGeneration : OsuTestCase
public class TestSceneAutoGeneration : OsuTestScene
{
[Test]
public void TestSingleNote()

View File

@ -13,6 +13,7 @@ using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mania.UI.Components;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Tests.Visual;
using osuTK;
@ -21,7 +22,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseColumn : ManiaInputTestCase
public class TestSceneColumn : ManiaInputTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -31,9 +32,12 @@ namespace osu.Game.Rulesets.Mania.Tests
typeof(ColumnHitObjectArea)
};
[Cached(typeof(IReadOnlyList<Mod>))]
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
private readonly List<Column> columns = new List<Column>();
public TestCaseColumn()
public TestSceneColumn()
: base(2)
{
}

View File

@ -11,11 +11,11 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseEditor : EditorTestCase
public class TestSceneEditor : EditorTestScene
{
private readonly Bindable<ManiaScrollingDirection> direction = new Bindable<ManiaScrollingDirection>();
public TestCaseEditor()
public TestSceneEditor()
: base(new ManiaRuleset())
{
AddStep("upwards scroll", () => direction.Value = ManiaScrollingDirection.Up);

View File

@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Tests
{
public class TestCaseHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestCase
public class TestSceneHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHoldNote((HoldNote)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new HoldNotePlacementBlueprint();

View File

@ -15,14 +15,14 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
public class TestCaseHoldNoteSelectionBlueprint : ManiaSelectionBlueprintTestCase
public class TestSceneHoldNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene
{
private readonly DrawableHoldNote drawableObject;
protected override Container<Drawable> Content => content ?? base.Content;
private readonly Container content;
public TestCaseHoldNoteSelectionBlueprint()
public TestSceneHoldNoteSelectionBlueprint()
{
var holdNote = new HoldNote { Column = 0, Duration = 1000 };
holdNote.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());

View File

@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Tests
{
public class TestCaseNotePlacementBlueprint : ManiaPlacementBlueprintTestCase
public class TestSceneNotePlacementBlueprint : ManiaPlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableNote((Note)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new NotePlacementBlueprint();

View File

@ -15,14 +15,14 @@ using osuTK;
namespace osu.Game.Rulesets.Mania.Tests
{
public class TestCaseNoteSelectionBlueprint : ManiaSelectionBlueprintTestCase
public class TestSceneNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene
{
private readonly DrawableNote drawableObject;
protected override Container<Drawable> Content => content ?? base.Content;
private readonly Container content;
public TestCaseNoteSelectionBlueprint()
public TestSceneNoteSelectionBlueprint()
{
var note = new Note { Column = 0 };
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());

View File

@ -11,10 +11,10 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Objects.Drawables;
@ -27,7 +27,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseNotes : OsuTestCase
public class TestSceneNotes : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Mania.Tests
content = new Container { RelativeSizeAxes = Axes.Both }
}
},
new SpriteText
new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
@ -168,11 +168,13 @@ namespace osu.Game.Rulesets.Mania.Tests
foreach (var nested in obj.NestedHitObjects)
{
double finalPosition = (nested.HitObject.StartTime - obj.HitObject.StartTime) / endTime.Duration;
switch (direction)
{
case ScrollingDirection.Up:
nested.Y = (float)(finalPosition * content.DrawHeight);
break;
case ScrollingDirection.Down:
nested.Y = (float)(-finalPosition * content.DrawHeight);
break;

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@ -13,6 +14,7 @@ using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Tests.Visual;
using osuTK;
@ -20,15 +22,18 @@ using osuTK;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseStage : ManiaInputTestCase
public class TestSceneStage : ManiaInputTestScene
{
private const int columns = 4;
[Cached(typeof(IReadOnlyList<Mod>))]
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
private readonly List<ManiaStage> stages = new List<ManiaStage>();
private FillFlowContainer<ScrollingTestContainer> fill;
public TestCaseStage()
public TestSceneStage()
: base(columns)
{
}

View File

@ -2,8 +2,8 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup>

View File

@ -48,6 +48,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
if (IsForCurrentRuleset)
{
TargetColumns = (int)Math.Max(1, roundedCircleSize);
if (TargetColumns >= 10)
{
TargetColumns = TargetColumns / 2;

View File

@ -179,6 +179,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
int usableColumns = TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects;
int nextColumn = GetRandomColumn();
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
{
// Find available column
@ -217,6 +218,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
nextColumn = FindAvailableColumn(nextColumn, PreviousPattern);
int lastColumn = nextColumn;
for (int i = 0; i < noteCount; i++)
{
addToPattern(pattern, nextColumn, startTime, startTime);
@ -299,6 +301,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
int interval = Random.Next(1, TotalColumns - (legacy ? 1 : 0));
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
for (int i = 0; i <= spanCount; i++)
{
addToPattern(pattern, nextColumn, startTime, startTime);
@ -341,16 +344,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
p3 = 0;
p4 = 0;
break;
case 3:
p2 = Math.Min(p2, 0.1);
p3 = 0;
p4 = 0;
break;
case 4:
p2 = Math.Min(p2, 0.3);
p3 = Math.Min(p3, 0.04);
p4 = 0;
break;
case 5:
p2 = Math.Min(p2, 0.34);
p3 = Math.Min(p3, 0.1);
@ -440,6 +446,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);
var rowPattern = new Pattern();
for (int i = 0; i <= spanCount; i++)
{
if (!(ignoreHead && startTime == HitObject.StartTime))

View File

@ -38,9 +38,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
case 8 when HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000:
addToPattern(pattern, 0, generateHold);
break;
case 8:
addToPattern(pattern, FindAvailableColumn(GetRandomColumn(), PreviousPattern), generateHold);
break;
default:
if (TotalColumns > 0)
addToPattern(pattern, GetRandomColumn(), generateHold);

View File

@ -233,6 +233,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
noteCount = Math.Min(noteCount, TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects);
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
for (int i = 0; i < noteCount; i++)
{
nextColumn = allowStacking
@ -303,6 +304,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
int columnLimit = (TotalColumns % 2 == 0 ? TotalColumns : TotalColumns - 1) / 2;
int nextColumn = GetRandomColumn(upperBound: columnLimit);
for (int i = 0; i < noteCount; i++)
{
nextColumn = FindAvailableColumn(nextColumn, upperBound: columnLimit, patterns: pattern);
@ -340,18 +342,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
p4 = 0;
p5 = 0;
break;
case 3:
p2 = Math.Min(p2, 0.1);
p3 = 0;
p4 = 0;
p5 = 0;
break;
case 4:
p2 = Math.Min(p2, 0.23);
p3 = Math.Min(p3, 0.04);
p4 = 0;
p5 = 0;
break;
case 5:
p3 = Math.Min(p3, 0.15);
p4 = Math.Min(p4, 0.03);
@ -384,20 +389,24 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
p2 = 0;
p3 = 0;
break;
case 3:
centreProbability = Math.Min(centreProbability, 0.03);
p2 = 0;
p3 = 0;
break;
case 4:
centreProbability = 0;
p2 = Math.Min(p2 * 2, 0.2);
p3 = 0;
break;
case 5:
centreProbability = Math.Min(centreProbability, 0.03);
p3 = 0;
break;
case 6:
centreProbability = 0;
p2 = Math.Min(p2 * 2, 0.5);

View File

@ -158,6 +158,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
// Ensure that we have at least one free column, so that an endless loop is avoided
bool hasValidColumns = false;
for (int i = lowerBound.Value; i < upperBound.Value; i++)
{
hasValidColumns = isValid(i);

View File

@ -1,10 +1,12 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Framework.Graphics;
using osuTK;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
@ -14,8 +16,8 @@ namespace osu.Game.Rulesets.Mania.Edit
{
public new IScrollingInfo ScrollingInfo => base.ScrollingInfo;
public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap)
public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
: base(ruleset, beatmap, mods)
{
}

View File

@ -11,6 +11,7 @@ using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Game.Rulesets.Mania.Edit.Blueprints;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
@ -41,9 +42,9 @@ namespace osu.Game.Rulesets.Mania.Edit
public int TotalColumns => ((ManiaPlayfield)DrawableRuleset.Playfield).TotalColumns;
protected override DrawableRuleset<ManiaHitObject> CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
protected override DrawableRuleset<ManiaHitObject> CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
{
DrawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap);
DrawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods);
// This is the earliest we can cache the scrolling info to ourselves, before masks are added to the hierarchy and inject it
dependencies.CacheAs(DrawableRuleset.ScrollingInfo);
@ -65,6 +66,7 @@ namespace osu.Game.Rulesets.Mania.Edit
{
case DrawableNote note:
return new NoteSelectionBlueprint(note);
case DrawableHoldNote holdNote:
return new HoldNoteSelectionBlueprint(holdNote);
}

View File

@ -10,5 +10,17 @@ namespace osu.Game.Rulesets.Mania.Judgements
public override bool AffectsCombo => false;
protected override int NumericResultFor(HitResult result) => 20;
protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
case HitResult.Miss:
return 0;
default:
return 0.040;
}
}
}
}

View File

@ -14,16 +14,47 @@ namespace osu.Game.Rulesets.Mania.Judgements
{
default:
return 0;
case HitResult.Meh:
return 50;
case HitResult.Ok:
return 100;
case HitResult.Good:
return 200;
case HitResult.Great:
case HitResult.Perfect:
return 300;
}
}
protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
case HitResult.Miss:
return -0.125;
case HitResult.Meh:
return 0.005;
case HitResult.Ok:
return 0.010;
case HitResult.Good:
return 0.035;
case HitResult.Great:
return 0.055;
case HitResult.Perfect:
return 0.065;
default:
return 0;
}
}
}
}

View File

@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mania
{
public class ManiaRuleset : Ruleset
{
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap) => new DrawableManiaRuleset(this, beatmap);
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableManiaRuleset(this, beatmap, mods);
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score);
@ -117,6 +117,7 @@ namespace osu.Game.Rulesets.Mania
new ManiaModNoFail(),
new MultiMod(new ManiaModHalfTime(), new ManiaModDaycore()),
};
case ModType.DifficultyIncrease:
return new Mod[]
{
@ -126,6 +127,7 @@ namespace osu.Game.Rulesets.Mania
new MultiMod(new ManiaModFadeIn(), new ManiaModHidden()),
new ManiaModFlashlight(),
};
case ModType.Conversion:
return new Mod[]
{
@ -142,16 +144,19 @@ namespace osu.Game.Rulesets.Mania
new ManiaModDualStages(),
new ManiaModMirror(),
};
case ModType.Automation:
return new Mod[]
{
new MultiMod(new ManiaModAutoplay(), new ModCinema()),
};
case ModType.Fun:
return new Mod[]
{
new MultiMod(new ModWindUp<ManiaHitObject>(), new ModWindDown<ManiaHitObject>())
};
default:
return new Mod[] { };
}
@ -214,6 +219,7 @@ namespace osu.Game.Rulesets.Mania
SpecialAction = ManiaAction.Special1,
NormalActionStart = ManiaAction.Key1,
}.GenerateKeyBindingsFor(variant, out _);
case PlayfieldType.Dual:
int keys = getDualStageKeyCount(variant);
@ -271,6 +277,7 @@ namespace osu.Game.Rulesets.Mania
{
default:
return $"{variant}K";
case PlayfieldType.Dual:
{
var keys = getDualStageKeyCount(variant);

View File

@ -7,6 +7,7 @@ using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Scoring;

View File

@ -65,6 +65,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
case ArmedState.Miss:
this.FadeOut(150, Easing.In).Expire();
break;
case ArmedState.Hit:
this.FadeOut(150, Easing.OutQuint).Expire();
break;

View File

@ -5,7 +5,7 @@ using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
using osu.Game.Rulesets.Scoring;

View File

@ -7,6 +7,7 @@ using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
@ -144,6 +145,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
const float animation_length = 50;
Foreground.ClearTransforms(false, nameof(Foreground.Colour));
if (hitting)
{
// wait for the next sync point

View File

@ -4,6 +4,7 @@
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osuTK.Graphics;

View File

@ -28,6 +28,7 @@ namespace osu.Game.Rulesets.Mania.Replays
var normalAction = ManiaAction.Key1;
var specialAction = ManiaAction.Special1;
int totalCounter = 0;
foreach (var stage in Beatmap.Stages)
{
for (int i = 0; i < stage.Columns; i++)
@ -51,6 +52,7 @@ namespace osu.Game.Rulesets.Mania.Replays
var pointGroups = generateActionPoints().GroupBy(a => a.Time).OrderBy(g => g.First().Time);
var actions = new List<ManiaAction>();
foreach (var group in pointGroups)
{
foreach (var point in group)
@ -60,6 +62,7 @@ namespace osu.Game.Rulesets.Mania.Replays
case HitPoint _:
actions.Add(columnActions[point.Column]);
break;
case ReleasePoint _:
actions.Remove(columnActions[point.Column]);
break;

View File

@ -39,6 +39,7 @@ namespace osu.Game.Rulesets.Mania.Replays
int activeColumns = (int)(legacyFrame.MouseX ?? 0);
int counter = 0;
while (activeColumns > 0)
{
var isSpecial = stage.IsSpecialColumn(counter);

View File

@ -3,7 +3,6 @@
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
@ -28,36 +27,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
/// </summary>
private const double hp_multiplier_max = 1;
/// <summary>
/// The default BAD hit HP increase.
/// </summary>
private const double hp_increase_bad = 0.005;
/// <summary>
/// The default OK hit HP increase.
/// </summary>
private const double hp_increase_ok = 0.010;
/// <summary>
/// The default GOOD hit HP increase.
/// </summary>
private const double hp_increase_good = 0.035;
/// <summary>
/// The default tick hit HP increase.
/// </summary>
private const double hp_increase_tick = 0.040;
/// <summary>
/// The default GREAT hit HP increase.
/// </summary>
private const double hp_increase_great = 0.055;
/// <summary>
/// The default PERFECT hit HP increase.
/// </summary>
private const double hp_increase_perfect = 0.065;
/// <summary>
/// The MISS HP multiplier at OD = 0.
/// </summary>
@ -73,11 +42,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
/// </summary>
private const double hp_multiplier_miss_max = 1;
/// <summary>
/// The default MISS HP increase.
/// </summary>
private const double hp_increase_miss = -0.125;
/// <summary>
/// The MISS HP multiplier. This is multiplied to the miss hp increase.
/// </summary>
@ -88,10 +52,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
/// </summary>
private double hpMultiplier = 1;
public ManiaScoreProcessor()
{
}
public ManiaScoreProcessor(DrawableRuleset<ManiaHitObject> drawableRuleset)
: base(drawableRuleset)
{
@ -122,42 +82,8 @@ namespace osu.Game.Rulesets.Mania.Scoring
}
}
protected override void ApplyResult(JudgementResult result)
{
base.ApplyResult(result);
bool isTick = result.Judgement is HoldNoteTickJudgement;
if (isTick)
{
if (result.IsHit)
Health.Value += hpMultiplier * hp_increase_tick;
}
else
{
switch (result.Type)
{
case HitResult.Miss:
Health.Value += hpMissMultiplier * hp_increase_miss;
break;
case HitResult.Meh:
Health.Value += hpMultiplier * hp_increase_bad;
break;
case HitResult.Ok:
Health.Value += hpMultiplier * hp_increase_ok;
break;
case HitResult.Good:
Health.Value += hpMultiplier * hp_increase_good;
break;
case HitResult.Great:
Health.Value += hpMultiplier * hp_increase_great;
break;
case HitResult.Perfect:
Health.Value += hpMultiplier * hp_increase_perfect;
break;
}
}
}
protected override double HealthAdjustmentFactorFor(JudgementResult result)
=> result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier;
public override HitWindows CreateHitWindows() => new ManiaHitWindows();
}

View File

@ -6,6 +6,7 @@ using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.UI;

View File

@ -7,6 +7,7 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Bindings;
using osu.Game.Graphics;

View File

@ -18,6 +18,7 @@ using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;
@ -39,8 +40,8 @@ namespace osu.Game.Rulesets.Mania.UI
private readonly Bindable<ManiaScrollingDirection> configDirection = new Bindable<ManiaScrollingDirection>();
public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap)
public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
: base(ruleset, beatmap, mods)
{
// Generate the bar lines
double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue;
@ -56,6 +57,7 @@ namespace osu.Game.Rulesets.Mania.UI
double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time - point.BeatLength : lastObjectTime + point.BeatLength * (int)point.TimeSignature;
int index = 0;
for (double t = timingPoints[i].Time; Precision.DefinitelyBigger(endTime, t); t += point.BeatLength, index++)
{
barLines.Add(new BarLine
@ -104,8 +106,10 @@ namespace osu.Game.Rulesets.Mania.UI
{
case HoldNote holdNote:
return new DrawableHoldNote(holdNote);
case Note note:
return new DrawableNote(note);
default:
return null;
}

View File

@ -4,6 +4,7 @@
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.MathUtils;
using osu.Game.Rulesets.Mania.Objects.Drawables;

View File

@ -38,6 +38,7 @@ namespace osu.Game.Rulesets.Mania.UI
var normalColumnAction = ManiaAction.Key1;
var specialColumnAction = ManiaAction.Special1;
int firstColumnIndex = 0;
for (int i = 0; i < stageDefinitions.Count; i++)
{
var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction);
@ -92,6 +93,7 @@ namespace osu.Game.Rulesets.Mania.UI
private ManiaStage getStageByColumn(int column)
{
int sum = 0;
foreach (var stage in stages)
{
sum = sum + stage.Columns.Count;

View File

@ -35,6 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests
yield return createConvertValue(nested);
break;
default:
yield return createConvertValue(hitObject);

View File

@ -1,11 +1,13 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Beatmaps;
using Decoder = osu.Game.Beatmaps.Formats.Decoder;
@ -22,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Tests
using (var reader = new StreamReader(stream))
{
var beatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo);
var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>());
var objects = converted.HitObjects.ToList();

View File

@ -7,9 +7,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseEditor : EditorTestCase
public class TestSceneEditor : EditorTestScene
{
public TestCaseEditor()
public TestSceneEditor()
: base(new OsuRuleset())
{
}

View File

@ -15,7 +15,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseGameplayCursor : OsuTestCase, IProvideCursor
public class TestSceneGameplayCursor : OsuTestScene, IProvideCursor
{
private GameplayCursorContainer cursorContainer;

View File

@ -19,7 +19,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseHitCircle : OsuTestCase
public class TestSceneHitCircle : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -30,9 +30,8 @@ namespace osu.Game.Rulesets.Osu.Tests
protected override Container<Drawable> Content => content;
private int depthIndex;
protected readonly List<Mod> Mods = new List<Mod>();
public TestCaseHitCircle()
public TestSceneHitCircle()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
@ -68,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Tests
Depth = depthIndex++
};
foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
foreach (var mod in Mods.Value.OfType<IApplicableToDrawableHitObjects>())
mod.ApplyToDrawableHitObjects(new[] { drawable });
Add(drawable);

View File

@ -10,13 +10,13 @@ using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseHitCircleHidden : TestCaseHitCircle
public class TestSceneHitCircleHidden : TestSceneHitCircle
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseHitCircleHidden()
public TestSceneHitCircleHidden()
{
Mods.Add(new OsuModHidden());
Mods.Value = new[] { new OsuModHidden() };
}
}
}

View File

@ -10,9 +10,9 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseHitCircleLongCombo : PlayerTestCase
public class TestSceneHitCircleLongCombo : PlayerTestScene
{
public TestCaseHitCircleLongCombo()
public TestSceneHitCircleLongCombo()
: base(new OsuRuleset())
{
}

View File

@ -11,7 +11,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseHitCirclePlacementBlueprint : PlacementBlueprintTestCase
public class TestSceneHitCirclePlacementBlueprint : PlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHitCircle((HitCircle)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new HitCirclePlacementBlueprint();

View File

@ -12,11 +12,11 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseHitCircleSelectionBlueprint : SelectionBlueprintTestCase
public class TestSceneHitCircleSelectionBlueprint : SelectionBlueprintTestScene
{
private readonly DrawableHitCircle drawableObject;
public TestCaseHitCircleSelectionBlueprint()
public TestSceneHitCircleSelectionBlueprint()
{
var hitCircle = new HitCircle { Position = new Vector2(256, 192) };
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 });

View File

@ -0,0 +1,19 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.Play;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestSceneOsuFlashlight : TestSceneOsuPlayer
{
protected override Player CreatePlayer(Ruleset ruleset)
{
Mods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), };
return base.CreatePlayer(ruleset);
}
}
}

View File

@ -7,9 +7,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseOsuPlayer : PlayerTestCase
public class TestSceneOsuPlayer : PlayerTestScene
{
public TestCaseOsuPlayer()
public TestSceneOsuPlayer()
: base(new OsuRuleset())
{
}

View File

@ -12,14 +12,14 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseResumeOverlay : ManualInputManagerTestCase
public class TestSceneResumeOverlay : ManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(OsuResumeOverlay),
};
public TestCaseResumeOverlay()
public TestSceneResumeOverlay()
{
ManualOsuInputManager osuInputManager;
CursorContainer cursor;

View File

@ -7,7 +7,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseShaking : TestCaseHitCircle
public class TestSceneShaking : TestSceneHitCircle
{
public override void Add(Drawable drawable)
{

View File

@ -27,7 +27,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseSlider : OsuTestCase
public class TestSceneSlider : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -44,9 +44,8 @@ namespace osu.Game.Rulesets.Osu.Tests
protected override Container<Drawable> Content => content;
private int depthIndex;
protected readonly List<Mod> Mods = new List<Mod>();
public TestCaseSlider()
public TestSceneSlider()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
@ -292,7 +291,7 @@ namespace osu.Game.Rulesets.Osu.Tests
Depth = depthIndex++
};
foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
foreach (var mod in Mods.Value.OfType<IApplicableToDrawableHitObjects>())
mod.ApplyToDrawableHitObjects(new[] { drawable });
drawable.OnNewResult += onNewResult;

View File

@ -10,13 +10,13 @@ using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseSliderHidden : TestCaseSlider
public class TestSceneSliderHidden : TestSceneSlider
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseSliderHidden()
public TestSceneSliderHidden()
{
Mods.Add(new OsuModHidden());
Mods.Value = new[] { new OsuModHidden() };
}
}
}

View File

@ -26,7 +26,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSliderInput : RateAdjustedBeatmapTestCase
public class TestSceneSliderInput : RateAdjustedBeatmapTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -353,6 +353,8 @@ namespace osu.Game.Rulesets.Osu.Tests
{
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
protected override bool PauseOnFocusLost => false;
public ScoreAccessibleReplayPlayer(Score score)
: base(score, false, false)
{

View File

@ -11,7 +11,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSliderPlacementBlueprint : PlacementBlueprintTestCase
public class TestSceneSliderPlacementBlueprint : PlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSlider((Slider)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new SliderPlacementBlueprint();

View File

@ -17,7 +17,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSliderSelectionBlueprint : SelectionBlueprintTestCase
public class TestSceneSliderSelectionBlueprint : SelectionBlueprintTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private readonly DrawableSlider drawableObject;
public TestCaseSliderSelectionBlueprint()
public TestSceneSliderSelectionBlueprint()
{
var slider = new Slider
{

View File

@ -18,7 +18,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseSpinner : OsuTestCase
public class TestSceneSpinner : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -31,9 +31,8 @@ namespace osu.Game.Rulesets.Osu.Tests
protected override Container<Drawable> Content => content;
private int depthIndex;
protected readonly List<Mod> Mods = new List<Mod>();
public TestCaseSpinner()
public TestSceneSpinner()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
@ -57,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Tests
Depth = depthIndex++
};
foreach (var mod in Mods.OfType<IApplicableToDrawableHitObjects>())
foreach (var mod in Mods.Value.OfType<IApplicableToDrawableHitObjects>())
mod.ApplyToDrawableHitObjects(new[] { drawable });
Add(drawable);

View File

@ -10,13 +10,13 @@ using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseSpinnerHidden : TestCaseSpinner
public class TestSceneSpinnerHidden : TestSceneSpinner
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseSpinnerHidden()
public TestSceneSpinnerHidden()
{
Mods.Add(new OsuModHidden());
Mods.Value = new[] { new OsuModHidden() };
}
}
}

View File

@ -11,7 +11,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSpinnerPlacementBlueprint : PlacementBlueprintTestCase
public class TestSceneSpinnerPlacementBlueprint : PlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSpinner((Spinner)hitObject);

View File

@ -17,7 +17,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSpinnerSelectionBlueprint : SelectionBlueprintTestCase
public class TestSceneSpinnerSelectionBlueprint : SelectionBlueprintTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private readonly DrawableSpinner drawableSpinner;
public TestCaseSpinnerSelectionBlueprint()
public TestSceneSpinnerSelectionBlueprint()
{
var spinner = new Spinner
{

View File

@ -2,8 +2,8 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup>

View File

@ -44,12 +44,14 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
if (endIndex < 0) throw new ArgumentOutOfRangeException(nameof(endIndex), $"{nameof(endIndex)} cannot be less than 0.");
int extendedEndIndex = endIndex;
if (endIndex < beatmap.HitObjects.Count - 1)
{
// Extend the end index to include objects they are stacked on
for (int i = endIndex; i >= startIndex; i--)
{
int stackBaseIndex = i;
for (int n = stackBaseIndex + 1; n < beatmap.HitObjects.Count; n++)
{
OsuHitObject stackBaseObject = beatmap.HitObjects[stackBaseIndex];
@ -87,6 +89,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
//Reverse pass for stack calculation.
int extendedStartIndex = startIndex;
for (int i = extendedEndIndex; i > startIndex; i--)
{
int n = i;
@ -138,6 +141,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
if (objectN is Slider && Vector2Extensions.Distance(objectN.EndPosition, objectI.Position) < stack_distance)
{
int offset = objectI.StackHeight - objectN.StackHeight + 1;
for (int j = n + 1; j <= i; j++)
{
//For each object which was declared under this slider, we will offset it to appear *below* the slider end (rather than above).

View File

@ -109,6 +109,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
aimValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8f) / Math.Pow(beatmapMaxCombo, 0.8f), 1.0f);
double approachRateFactor = 1.0f;
if (Attributes.ApproachRate > 10.33f)
approachRateFactor += 0.3f * (Attributes.ApproachRate - 10.33f);
else if (Attributes.ApproachRate < 8.0f)

View File

@ -56,6 +56,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
{
// We will scale distances by this factor, so we can assume a uniform CircleSize among beatmaps.
float scalingFactor = normalized_radius / (float)BaseObject.Radius;
if (BaseObject.Radius < 30)
{
float smallCircleBonus = Math.Min(30 - (float)BaseObject.Radius, 5) / 50;

View File

@ -42,9 +42,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
speedBonus = 1 + Math.Pow((min_speed_bonus - deltaTime) / speed_balancing_factor, 2);
double angleBonus = 1.0;
if (osuCurrent.Angle != null && osuCurrent.Angle.Value < angle_bonus_begin)
{
angleBonus = 1 + Math.Pow(Math.Sin(1.5 * (angle_bonus_begin - osuCurrent.Angle.Value)), 2) / 3.57;
if (osuCurrent.Angle.Value < pi_over_2)
{
angleBonus = 1.28;

View File

@ -37,6 +37,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
case SliderPosition.Start:
Position = slider.StackedPosition + slider.Path.PositionAt(0);
break;
case SliderPosition.End:
Position = slider.StackedPosition + slider.Path.PositionAt(1);
break;

View File

@ -62,6 +62,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
case PlacementState.Initial:
HitObject.Position = e.MousePosition;
return true;
case PlacementState.Body:
cursor = e.MousePosition - HitObject.Position;
return true;
@ -77,6 +78,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
case PlacementState.Initial:
beginCurve();
break;
case PlacementState.Body:
switch (e.Button)
{

View File

@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.UI;
using osuTK;
@ -10,8 +12,8 @@ namespace osu.Game.Rulesets.Osu.Edit
{
public class DrawableOsuEditRuleset : DrawableOsuRuleset
{
public DrawableOsuEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap)
public DrawableOsuEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
: base(ruleset, beatmap, mods)
{
}

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders;
@ -23,8 +24,8 @@ namespace osu.Game.Rulesets.Osu.Edit
{
}
protected override DrawableRuleset<OsuHitObject> CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
=> new DrawableOsuEditRuleset(ruleset, beatmap);
protected override DrawableRuleset<OsuHitObject> CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
=> new DrawableOsuEditRuleset(ruleset, beatmap, mods);
protected override IReadOnlyList<HitObjectCompositionTool> CompositionTools => new HitObjectCompositionTool[]
{
@ -41,8 +42,10 @@ namespace osu.Game.Rulesets.Osu.Edit
{
case DrawableHitCircle circle:
return new HitCircleSelectionBlueprint(circle);
case DrawableSlider slider:
return new SliderSelectionBlueprint(slider);
case DrawableSpinner spinner:
return new SpinnerSelectionBlueprint(spinner);
}

View File

@ -16,13 +16,33 @@ namespace osu.Game.Rulesets.Osu.Judgements
{
default:
return 0;
case HitResult.Meh:
return 50;
case HitResult.Good:
return 100;
case HitResult.Great:
return 300;
}
}
protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
case HitResult.Miss:
return -0.02;
case HitResult.Meh:
case HitResult.Good:
case HitResult.Great:
return 0.01;
default:
return 0;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More