├── .editorconfig
├── .gitattributes
├── .github
├── dependabot.yml
└── workflows
│ ├── dotnet-core.yml
│ └── release.yml
├── .gitignore
├── .vscode
├── launch.json
└── tasks.json
├── Directory.Build.props
├── LICENSE
├── README.md
├── assets
└── rush.png
├── osu.Game.Rulesets.Rush.Tests
├── Beatmaps
│ ├── BeatmapConversionDecidingTest.cs
│ └── CraftedBeatmapConversionTest.cs
├── Replay
│ └── RushReplayFrameTest.cs
├── Visual
│ ├── TestSceneFeverBar.cs
│ ├── TestSceneGround.cs
│ ├── TestSceneMiniBoss.cs
│ ├── TestSceneOsuGame.cs
│ ├── TestSceneRushAutoplay.cs
│ ├── TestSceneRushPlayer.cs
│ └── TestSceneTouchInputHandling.cs
├── VisualTestRunner.cs
└── osu.Game.Rulesets.Rush.Tests.csproj
├── osu.Game.Rulesets.Rush.sln
├── osu.Game.Rulesets.Rush.sln.DotSettings
└── osu.Game.Rulesets.Rush
├── Beatmaps
├── RushBeatmap.cs
├── RushBeatmapConverter.cs
├── RushCraftedBeatmapConverter.cs
└── RushGeneratedBeatmapConverter.cs
├── Configuration
├── FeverActivationMode.cs
└── RushRulesetConfigManager.cs
├── Input
├── IKeyBindingTouchHandler.cs
├── RushInputManager.cs
├── RushMouseEventManager.cs
└── RushTouchEventManager.cs
├── Judgements
├── CollisionDamagingJudgement.cs
├── HeartJudgement.cs
├── RushFeverJudgement.cs
├── RushIgnoreJudgement.cs
├── RushJudgement.cs
├── RushJudgementResult.cs
├── RushTickJudgement.cs
└── SawbladeJudgement.cs
├── Mods
├── RushModAutoplay.cs
├── RushModCinema.cs
├── RushModDaycore.cs
├── RushModDoubleTime.cs
├── RushModFlashlight.cs
├── RushModHalfTime.cs
├── RushModNightcore.cs
├── RushModNoFail.cs
├── RushModPerfect.cs
└── RushModSuddenDeath.cs
├── Objects
├── Drawables
│ ├── DrawableDualHit.cs
│ ├── DrawableDualHitPart.cs
│ ├── DrawableFeverBonus.cs
│ ├── DrawableHeart.cs
│ ├── DrawableLanedHit.cs
│ ├── DrawableMiniBoss.cs
│ ├── DrawableMiniBossTick.cs
│ ├── DrawableMinion.cs
│ ├── DrawableRushHitObject.cs
│ ├── DrawableRushJudgement.cs
│ ├── DrawableSawblade.cs
│ ├── DrawableStarSheet.cs
│ ├── DrawableStarSheetCap.cs
│ ├── DrawableStarSheetHead.cs
│ ├── DrawableStarSheetTail.cs
│ ├── IDrawableLanedHit.cs
│ └── Pieces
│ │ ├── DualHitJoinPiece.cs
│ │ ├── DualHitPartPiece.cs
│ │ ├── HeartPiece.cs
│ │ ├── MiniBossPiece.cs
│ │ ├── MinionPiece.cs
│ │ ├── SawbladePiece.cs
│ │ ├── StarSheetBodyPiece.cs
│ │ └── StarSheetCapStarPiece.cs
├── DualHit.cs
├── DualHitPart.cs
├── FeverBonus.cs
├── Heart.cs
├── LanedHit.cs
├── LanedHitLane.cs
├── MiniBoss.cs
├── MiniBossTick.cs
├── Minion.cs
├── RushHitObject.cs
├── Sawblade.cs
├── StarSheet.cs
├── StarSheetHead.cs
└── StarSheetTail.cs
├── Replays
├── RushAutoGenerator.cs
├── RushFramedReplayInputHandler.cs
└── RushReplayFrame.cs
├── Resources
└── Textures
│ ├── Effects
│ └── explosion.png
│ ├── MiniBoss
│ ├── pippidon_boss_0.png
│ ├── pippidon_boss_1.png
│ ├── pippidon_boss_hurt_0.png
│ ├── pippidon_boss_hurt_1.png
│ └── pippidon_boss_hurt_2.png
│ ├── Minion
│ ├── pippidon_air_0.png
│ ├── pippidon_air_1.png
│ ├── pippidon_air_hit.png
│ ├── pippidon_ground_0.png
│ ├── pippidon_ground_1.png
│ └── pippidon_ground_hit.png
│ └── Player
│ ├── Attack__000.png
│ ├── Attack__001.png
│ ├── Attack__002.png
│ ├── Attack__003.png
│ ├── Attack__004.png
│ ├── Attack__005.png
│ ├── Attack__006.png
│ ├── Attack__007.png
│ ├── Attack__008.png
│ ├── Attack__009.png
│ ├── Dead__000.png
│ ├── Jump_Attack__000.png
│ ├── Jump_Attack__001.png
│ ├── Jump_Attack__002.png
│ ├── Jump_Attack__003.png
│ ├── Jump_Attack__004.png
│ ├── Jump_Attack__005.png
│ ├── Jump_Attack__006.png
│ ├── Jump_Attack__007.png
│ ├── Jump_Attack__008.png
│ ├── Jump_Attack__009.png
│ ├── Jump__000.png
│ ├── Jump__001.png
│ ├── Jump__002.png
│ ├── Jump__003.png
│ ├── Jump__004.png
│ ├── Jump__005.png
│ ├── Jump__006.png
│ ├── Jump__007.png
│ ├── Jump__008.png
│ ├── Jump__009.png
│ ├── Run__000.png
│ ├── Run__001.png
│ ├── Run__002.png
│ ├── Run__003.png
│ ├── Run__004.png
│ ├── Run__005.png
│ ├── Run__006.png
│ ├── Run__007.png
│ ├── Run__008.png
│ ├── Run__009.png
│ ├── Slide__000.png
│ ├── Slide__001.png
│ ├── Slide__002.png
│ ├── Slide__003.png
│ ├── Slide__004.png
│ ├── Slide__005.png
│ ├── Slide__006.png
│ ├── Slide__007.png
│ ├── Slide__008.png
│ └── Slide__009.png
├── RushDifficultyCalculator.cs
├── RushRuleset.cs
├── RushSkinComponent.cs
├── RushSkinComponents.cs
├── Scoring
├── HeartHitWindows.cs
├── RushHealthProcessor.cs
├── RushHitWindows.cs
├── RushScoreProcessor.cs
└── SawbladeHitWindows.cs
├── UI
├── ActionBeatSyncedContainer.cs
├── DefaultHitExplosion.cs
├── DrawableRushRuleset.cs
├── Fever
│ ├── FeverProcessor.cs
│ └── RushFeverBar.cs
├── Ground
│ ├── DefaultGround.cs
│ └── GroundDisplay.cs
├── HealthText.cs
├── HeartHitExplosion.cs
├── HitTarget.cs
├── LanePlayfield.cs
├── RushHitPolicy.cs
├── RushPlayerSprite.cs
├── RushPlayfield.cs
├── RushReplayRecorder.cs
├── RushSettingsSubsection.cs
└── StarSheetHitExplosion.cs
└── osu.Game.Rulesets.Rush.csproj
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Autodetect text files and ensure that we normalise their
2 | # line endings to lf internally. When checked out they may
3 | # use different line endings.
4 | * text=auto
5 |
6 | # Check out with crlf (Windows) line endings
7 | *.sln text eol=crlf
8 | *.csproj text eol=crlf
9 | *.cs text diff=csharp eol=crlf
10 |
11 | # Check out with lf (UNIX) line endings
12 | .gitignore text eol=lf
13 | .gitattributes text eol=lf
14 | *.sh text eol=lf
15 | *.md text eol=lf
16 | *.yml text eol=lf
17 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "nuget"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 |
--------------------------------------------------------------------------------
/.github/workflows/dotnet-core.yml:
--------------------------------------------------------------------------------
1 | name: .NET Core
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v2
15 | - name: Setup .NET Core
16 | uses: actions/setup-dotnet@v1
17 | - name: Install dependencies
18 | run: dotnet restore
19 | - name: Build
20 | run: dotnet build --configuration Development --no-restore
21 | - name: Test
22 | run: dotnet test --no-restore --verbosity normal
23 | - name: Upload Artifact
24 | uses: actions/upload-artifact@v4
25 | with:
26 | name: Rush (dev build)
27 | path: osu.Game.Rulesets.Rush/bin/Development/net8.0/osu.Game.Rulesets.Rush-dev.dll
28 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Tagged Release
2 | on:
3 | push:
4 | tags: ['*']
5 |
6 | jobs:
7 | build:
8 | name: Build and Create Release
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - name: Checkout repository
13 | uses: actions/checkout@v2
14 | - name: Fetch all tags
15 | run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
16 | - name: Get current tag
17 | run: echo "CURRENT_TAG=$(git describe --abbrev=0 --tags $(git rev-list --tags --max-count=1))" >> $GITHUB_ENV
18 | - name: Install dependencies
19 | run: dotnet restore
20 | - name: Build
21 | run: dotnet build osu.Game.Rulesets.Rush --configuration Release -p:version=${{env.CURRENT_TAG}} --no-restore
22 | - name: Create Release
23 | id: create_release
24 | uses: actions/create-release@latest
25 | env:
26 | GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
27 | with:
28 | tag_name: ${{ github.ref }}
29 | release_name: ${{ github.ref }}
30 | body: |
31 | Tagged release ${{ github.ref }}
32 | draft: true
33 | prerelease: true
34 | - name: Upload Release Asset
35 | id: upload-release-asset
36 | uses: actions/upload-release-asset@master
37 | env:
38 | GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
39 | with:
40 | upload_url: ${{ steps.create_release.outputs.upload_url }}
41 | asset_path: ./osu.Game.Rulesets.Rush/bin/Release/net8.0/osu.Game.Rulesets.Rush.dll
42 | asset_name: osu.Game.Rulesets.Rush.dll
43 | asset_content_type: application/vnd.microsoft.portable-executable
44 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Rush for osu! (Tests, Debug)",
6 | "type": "coreclr",
7 | "request": "launch",
8 | "program": "dotnet",
9 | "args": [
10 | "${workspaceRoot}/osu.Game.Rulesets.Rush.Tests/bin/Debug/net8.0/osu.Game.Rulesets.Rush.Tests.dll"
11 | ],
12 | "cwd": "${workspaceRoot}",
13 | "preLaunchTask": "Build tests (Debug)",
14 | "console": "internalConsole"
15 | },
16 | {
17 | "name": "Rush for osu! (Tests, Release)",
18 | "type": "coreclr",
19 | "request": "launch",
20 | "program": "dotnet",
21 | "args": [
22 | "${workspaceRoot}/osu.Game.Rulesets.Rush.Tests/bin/Release/net8.0/osu.Game.Rulesets.Rush.Tests.dll"
23 | ],
24 | "cwd": "${workspaceRoot}",
25 | "preLaunchTask": "Build tests (Release)",
26 | "console": "internalConsole"
27 | },
28 | {
29 | "name": "Rush for osu! (Tests, Development)",
30 | "type": "coreclr",
31 | "request": "launch",
32 | "program": "dotnet",
33 | "args": [
34 | "${workspaceRoot}/osu.Game.Rulesets.Rush.Tests/bin/Development/net8.0/osu.Game.Rulesets.Rush.Tests.dll"
35 | ],
36 | "cwd": "${workspaceRoot}",
37 | "preLaunchTask": "Build tests (Development)",
38 | "console": "internalConsole"
39 | },
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "Build tests (Debug)",
6 | "type": "shell",
7 | "command": "dotnet",
8 | "args": [
9 | "build",
10 | "osu.Game.Rulesets.Rush.Tests",
11 | "/p:GenerateFullPaths=true",
12 | "/m",
13 | "/verbosity:m"
14 | ],
15 | "group": "build",
16 | "problemMatcher": "$msCompile"
17 | },
18 | {
19 | "label": "Build tests (Release)",
20 | "type": "shell",
21 | "command": "dotnet",
22 | "args": [
23 | "build",
24 | "osu.Game.Rulesets.Rush.Tests",
25 | "/p:Configuration=Release",
26 | "/p:GenerateFullPaths=true",
27 | "/m",
28 | "/verbosity:m"
29 | ],
30 | "group": "build",
31 | "problemMatcher": "$msCompile"
32 | },
33 | {
34 | "label": "Build tests (Development)",
35 | "type": "shell",
36 | "command": "dotnet",
37 | "args": [
38 | "build",
39 | "osu.Game.Rulesets.Rush.Tests",
40 | "/p:Configuration=Development",
41 | "/p:GenerateFullPaths=true",
42 | "/m",
43 | "/verbosity:m"
44 | ],
45 | "group": "build",
46 | "problemMatcher": "$msCompile"
47 | },
48 | // Test Tasks
49 | {
50 | "label": "Run tests (Debug)",
51 | "type": "shell",
52 | "command": "dotnet",
53 | "args": [
54 | "test",
55 | "/p:Configuration=Debug",
56 | ],
57 | "group": "test",
58 | "problemMatcher": "$msCompile"
59 | },
60 | {
61 | "label": "Run tests (Release)",
62 | "type": "shell",
63 | "command": "dotnet",
64 | "args": [
65 | "test",
66 | "/p:Configuration=Release",
67 | ],
68 | "group": "test",
69 | "problemMatcher": "$msCompile"
70 | }
71 | ]
72 | }
73 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | 8.0
4 | true
5 | true
6 | true
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2020 Shane Woolcock
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Rush!
4 | Custom ruleset for osu!lazer, based loosely on Muse Dash.
5 |
6 | Demo: https://youtu.be/tLs1cqeLJ1U
7 |
8 | Discord: https://discord.gg/2P9E8MS
9 |
10 | ## Status
11 | WIP but playable.
12 |
13 | ## Installation
14 |
15 | Prebuilt binary releases are available if you are looking to test or play and do not wish to compile yourself.
16 | | [Releases Page](https://github.com/swoolcock/rush/releases/) |
17 | | -------------|
18 |
19 | **NOTE**: osu!lazer runs custom rulesets only on desktop platforms (Windows, macOS, Linux) for the time being.
20 |
21 | The ruleset consists of a single DLL file that you'll need to place in the `rulesets` subdirectory of your osu!lazer installation.
22 |
23 | ### Installation instructions
24 |
25 | 1. Navigate to the osu!lazer data directory. You can do so by opening the settings panel in osu!lazer and clicking on the "open osu! folder" button. Alternatively you can directly navigate to the `rulesets` directory via your OS directory explorer at the following locations:
26 | - `%AppData%/osu/rulesets` on Windows
27 | - `~/.local/share/osu/rulesets` on Linux / macOS
28 |
29 | **NOTE**: If you have relocated your osu! data directory to another directory, the `rulesets` directory will be there instead.
30 |
31 | 2. Drag and drop the ruleset's DLL file into the `rulesets` directory.
32 |
33 | 3. Have fun!
34 | If osu!lazer was running while installing the ruleset, you may need to restart the game in order for the ruleset to appear.
35 |
36 | **NOTE**: Custom Rulesets do not automatically update alongside osu!lazer but have a compatibility mechanism to continue using them on newer game versions. However, some changes made game-side may break that compatibility and require installing a newer version of the ruleset.
37 | Thus it is recommended that you periodically head over to the releases page and replace the ruleset DLL in the `rulesets` directory with the latest available version.
38 |
39 | ## TODO
40 | * Better player sprite
41 | * Boss sprite during kiai sections
42 | * Hammers and other minion variants
43 | * Custom avatars/abilities via mods?
44 | * Editor (waiting on updates in lazer)
45 |
--------------------------------------------------------------------------------
/assets/rush.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/assets/rush.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/Beatmaps/BeatmapConversionDecidingTest.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using NUnit.Framework;
5 | using osu.Game.Beatmaps;
6 | using osu.Game.Rulesets.Rush.Beatmaps;
7 |
8 | namespace osu.Game.Rulesets.Rush.Tests.Beatmaps
9 | {
10 | [TestFixture]
11 | public class BeatmapConversionDecidingTest
12 | {
13 | [Test]
14 | public void TestCraftedTagCreatesCrafter()
15 | => Assert.That(converterForTag("crafted") is RushCraftedBeatmapConverter, Is.True);
16 |
17 | [Test]
18 | public void TestWrongCasedCraftedTagCreatesCrafter()
19 | => Assert.That(converterForTag("cRafTeD") is RushCraftedBeatmapConverter, Is.True);
20 |
21 | [Test]
22 | public void TestWordContainingCraftedTagCreatesGenerator()
23 | => Assert.That(converterForTag("handcraftedison") is RushGeneratedBeatmapConverter, Is.True);
24 |
25 | [Test]
26 | public void TestRandomTagCreatesGenerator()
27 | => Assert.That(converterForTag("one two something") is RushGeneratedBeatmapConverter, Is.True);
28 |
29 | [Test]
30 | public void TestNullTagCreatesGenerator()
31 | => Assert.That(converterForTag(null) is RushGeneratedBeatmapConverter, Is.True);
32 |
33 | private IBeatmapConverter converterForTag(string tags)
34 | {
35 | var beatmap = new Beatmap { BeatmapInfo = { Metadata = { Tags = tags } } };
36 | var wrapper = new RushBeatmapConverter(beatmap, new RushRuleset());
37 | return wrapper.BackedConverter;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/Beatmaps/CraftedBeatmapConversionTest.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using NUnit.Framework;
7 | using osu.Framework.Utils;
8 | using osu.Game.Rulesets.Objects;
9 | using osu.Game.Rulesets.Rush.Objects;
10 | using osu.Game.Tests.Beatmaps;
11 |
12 | namespace osu.Game.Rulesets.Rush.Tests.Beatmaps
13 | {
14 | [TestFixture]
15 | public class CraftedBeatmapConversionTest : BeatmapConversionTest
16 | {
17 | protected override string ResourceAssembly => typeof(RushRuleset).Namespace;
18 |
19 | // TODO: add tests for this
20 | //public void Test(string name) => base.Test(name);
21 |
22 | protected override IEnumerable CreateConvertValue(HitObject hitObject)
23 | {
24 | yield return new ConvertValue
25 | {
26 | StartTime = hitObject.StartTime,
27 | EndTime = hitObject.GetEndTime(),
28 | Lane = (hitObject as LanedHit)?.Lane,
29 | IsMinion = hitObject is Minion,
30 | IsStarSheet = hitObject is StarSheet,
31 | IsMiniBoss = hitObject is MiniBoss,
32 | IsSawblade = hitObject is Sawblade,
33 | HasHeart = hitObject is Heart /*|| (hitObject is LanedHit)?.HasHeart*/,
34 | IsHammer = false, // TODO
35 | IsNote = false, // TODO
36 | };
37 | }
38 |
39 | protected override Ruleset CreateRuleset() => new RushRuleset();
40 | }
41 |
42 | public struct ConvertValue : IEquatable
43 | {
44 | ///
45 | /// A sane value to account for osu!stable using ints everywhere.
46 | ///
47 | private const float conversion_lenience = 2;
48 |
49 | public double StartTime;
50 | public double EndTime;
51 | public LanedHitLane? Lane;
52 | public bool IsMinion;
53 | public bool IsStarSheet;
54 | public bool IsMiniBoss;
55 | public bool IsSawblade;
56 | public bool IsHammer;
57 | public bool HasHeart;
58 | public bool IsNote;
59 |
60 | public bool Equals(ConvertValue other)
61 | => Precision.AlmostEquals(StartTime, other.StartTime, conversion_lenience)
62 | && Precision.AlmostEquals(EndTime, other.EndTime, conversion_lenience)
63 | && Lane == other.Lane
64 | && IsMinion == other.IsMinion
65 | && IsStarSheet == other.IsStarSheet
66 | && IsSawblade == other.IsSawblade
67 | && IsHammer == other.IsHammer
68 | && HasHeart == other.HasHeart
69 | && IsNote == other.IsNote
70 | && IsMiniBoss == other.IsMiniBoss;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/Replay/RushReplayFrameTest.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using NUnit.Framework;
5 | using osu.Game.Beatmaps;
6 | using osu.Game.Rulesets.Rush.Input;
7 | using osu.Game.Rulesets.Rush.Replays;
8 |
9 | namespace osu.Game.Rulesets.Rush.Tests.Replay
10 | {
11 | [TestFixture]
12 | public class RushReplayFrameTest
13 | {
14 | [TestCase]
15 | [TestCase(RushAction.AirPrimary, RushAction.GroundPrimary)]
16 | [TestCase(RushAction.AirPrimary, RushAction.AirSecondary, RushAction.GroundQuaternary)]
17 | [TestCase(RushAction.GroundPrimary, RushAction.GroundSecondary)]
18 | [TestCase(RushAction.AirPrimary, RushAction.AirSecondary, RushAction.AirTertiary, RushAction.AirQuaternary, RushAction.GroundPrimary, RushAction.GroundSecondary, RushAction.GroundTertiary, RushAction.GroundTertiary)]
19 | public void TestParity(params RushAction[] actions)
20 | {
21 | var originalFrame = (RushReplayFrame)new RushRuleset().CreateConvertibleReplayFrame();
22 | var resultFrame = (RushReplayFrame)new RushRuleset().CreateConvertibleReplayFrame();
23 |
24 | resultFrame.FromLegacy(originalFrame.ToLegacy(new Beatmap()), new Beatmap());
25 |
26 | Assert.That(resultFrame.Actions, Is.EquivalentTo(originalFrame.Actions));
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/Visual/TestSceneFeverBar.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Allocation;
5 | using osu.Framework.Graphics;
6 | using osu.Game.Rulesets.Rush.UI.Fever;
7 | using osu.Game.Tests.Visual;
8 |
9 | namespace osu.Game.Rulesets.Rush.Tests.Visual
10 | {
11 | public partial class TestSceneFeverBar : OsuTestScene
12 | {
13 | [Cached]
14 | private readonly FeverProcessor feverProcessor = new FeverProcessor();
15 |
16 | public TestSceneFeverBar()
17 | {
18 | Children = new Drawable[]
19 | {
20 | feverProcessor,
21 | new FeverBar()
22 | {
23 | Anchor = Anchor.Centre,
24 | Origin = Anchor.Centre,
25 | Y = 0,
26 | }
27 | };
28 |
29 | AddSliderStep("Progress", 0, 1, 0, v => feverProcessor.FeverProgress.Value = v);
30 | AddToggleStep("Activated", v => feverProcessor.InFeverMode.Value = v);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/Visual/TestSceneGround.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Game.Rulesets.Rush.UI.Ground;
6 | using osu.Game.Tests.Visual;
7 |
8 | namespace osu.Game.Rulesets.Rush.Tests.Visual
9 | {
10 | public partial class TestSceneGround : OsuTestScene
11 | {
12 | public TestSceneGround()
13 | {
14 | Children = new Drawable[]
15 | {
16 | new GroundDisplay
17 | {
18 | RelativePositionAxes = Axes.Y,
19 | Y = 0.7f,
20 | },
21 | };
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/Visual/TestSceneMiniBoss.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using NUnit.Framework;
5 | using osu.Game.Beatmaps;
6 | using osu.Game.Rulesets.Rush.Beatmaps;
7 | using osu.Game.Rulesets.Rush.Objects;
8 | using osu.Game.Rulesets.Rush.UI;
9 | using osuTK.Input;
10 |
11 | namespace osu.Game.Rulesets.Rush.Tests.Visual
12 | {
13 | public partial class TestSceneMiniBoss : TestSceneRushPlayer
14 | {
15 | private const float mini_boss_time = 600f;
16 |
17 | protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
18 | {
19 | var beatmap = new RushBeatmap();
20 |
21 | for (int i = 0; i < mini_boss_time / 200f; i++)
22 | {
23 | beatmap.HitObjects.Add(new Minion
24 | {
25 | StartTime = i * 200,
26 | });
27 | }
28 |
29 | beatmap.HitObjects.Add(new MiniBoss
30 | {
31 | StartTime = mini_boss_time,
32 | Duration = 1000f,
33 | });
34 |
35 | return beatmap;
36 | }
37 |
38 | private PlayerTargetLane targetLane => ((DrawableRushRuleset)Player.DrawableRuleset).Playfield.PlayerSprite.Target;
39 |
40 | [Test]
41 | public void TestPlayerStateTransitionsAtCorrectTime()
42 | {
43 | AddStep("mash air actions", () => Scheduler.AddDelayed(() =>
44 | {
45 | InputManager.Click(MouseButton.Left);
46 | }, 50f, true));
47 |
48 | AddAssert("not in fight state", () => targetLane != PlayerTargetLane.MiniBoss);
49 | AddUntilStep("wait for fight state", () => targetLane == PlayerTargetLane.MiniBoss);
50 | AddAssert("time has reached mini-boss time", () => Player.GameplayClockContainer.CurrentTime >= mini_boss_time);
51 |
52 | AddStep("stop mashing", () => Scheduler.CancelDelayedTasks());
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/Visual/TestSceneOsuGame.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Allocation;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Graphics.Shapes;
7 | using osu.Game.Tests.Visual;
8 | using osuTK.Graphics;
9 |
10 | namespace osu.Game.Rulesets.Rush.Tests.Visual
11 | {
12 | public partial class TestSceneOsuGame : OsuTestScene
13 | {
14 | [BackgroundDependencyLoader]
15 | private void load()
16 | {
17 | Children = new Drawable[]
18 | {
19 | new Box
20 | {
21 | RelativeSizeAxes = Axes.Both,
22 | Colour = Color4.Black,
23 | },
24 | };
25 | AddGame(new OsuGame());
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/Visual/TestSceneRushAutoplay.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | namespace osu.Game.Rulesets.Rush.Tests.Visual
5 | {
6 | public partial class TestSceneRushAutoplay : TestSceneRushPlayer
7 | {
8 | protected override bool Autoplay => true;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/Visual/TestSceneRushPlayer.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using NUnit.Framework;
5 | using osu.Framework.Allocation;
6 | using osu.Framework.Bindables;
7 | using osu.Framework.Graphics;
8 | using osu.Game.Graphics.UserInterface;
9 | using osu.Game.Tests.Visual;
10 |
11 | namespace osu.Game.Rulesets.Rush.Tests.Visual
12 | {
13 | [TestFixture]
14 | public partial class TestSceneRushPlayer : PlayerTestScene
15 | {
16 | private readonly BindableBool pausedBindable = new BindableBool();
17 |
18 | protected new RushPlayer Player => (RushPlayer)base.Player;
19 |
20 | protected override TestPlayer CreatePlayer(Ruleset ruleset) => new RushPlayer();
21 |
22 | protected override Ruleset CreatePlayerRuleset() => new RushRuleset();
23 |
24 | [BackgroundDependencyLoader]
25 | private void load()
26 | {
27 | Add(new OsuCheckbox
28 | {
29 | LabelText = "Pause",
30 | RelativeSizeAxes = Axes.None,
31 | AutoSizeAxes = Axes.Y,
32 | Width = 100,
33 | Origin = Anchor.TopLeft,
34 | Anchor = Anchor.TopLeft,
35 | Margin = new MarginPadding { Top = 40f, Left = 10f },
36 | Depth = float.NegativeInfinity,
37 | Current = { BindTarget = pausedBindable }
38 | });
39 |
40 | pausedBindable.ValueChanged += e => Player?.SetGameplayClockPaused(e.NewValue);
41 | }
42 |
43 | protected partial class RushPlayer : TestPlayer
44 | {
45 | public void SetGameplayClockPaused(bool value)
46 | {
47 | if (GameplayClockContainer.IsPaused.Value && !value)
48 | GameplayClockContainer.Start();
49 | else if (!GameplayClockContainer.IsPaused.Value && value)
50 | GameplayClockContainer.Stop();
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/VisualTestRunner.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using osu.Framework;
6 | using osu.Framework.Platform;
7 | using osu.Game.Tests;
8 |
9 | namespace osu.Game.Rulesets.Rush.Tests
10 | {
11 | public static class VisualTestRunner
12 | {
13 | [STAThread]
14 | public static int Main(string[] args)
15 | {
16 | using (DesktopGameHost host = Host.GetSuitableDesktopHost(@"osu"))
17 | {
18 | host.Run(new OsuTestBrowser());
19 | return 0;
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.Tests/osu.Game.Rulesets.Rush.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | osu.Game.Rulesets.Rush.Tests.VisualTestRunner
4 | Debug;Release;Development
5 | AnyCPU
6 |
7 |
8 |
9 |
10 |
11 | false
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | WinExe
20 | net8.0
21 |
22 |
23 | true
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29123.88
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Rush", "osu.Game.Rulesets.Rush\osu.Game.Rulesets.Rush.csproj", "{5AE1F0F1-DAFA-46E7-959C-DA233B7C87E9}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Rush.Tests", "osu.Game.Rulesets.Rush.Tests\osu.Game.Rulesets.Rush.Tests.csproj", "{B4577C85-CB83-462A-BCE3-22FFEB16311D}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | Development|Any CPU = Development|Any CPU
15 | EndGlobalSection
16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
17 | {5AE1F0F1-DAFA-46E7-959C-DA233B7C87E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18 | {5AE1F0F1-DAFA-46E7-959C-DA233B7C87E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
19 | {5AE1F0F1-DAFA-46E7-959C-DA233B7C87E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
20 | {5AE1F0F1-DAFA-46E7-959C-DA233B7C87E9}.Release|Any CPU.Build.0 = Release|Any CPU
21 | {5AE1F0F1-DAFA-46E7-959C-DA233B7C87E9}.Development|Any CPU.ActiveCfg = Development|Any CPU
22 | {5AE1F0F1-DAFA-46E7-959C-DA233B7C87E9}.Development|Any CPU.Build.0 = Development|Any CPU
23 | {B4577C85-CB83-462A-BCE3-22FFEB16311D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {B4577C85-CB83-462A-BCE3-22FFEB16311D}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {B4577C85-CB83-462A-BCE3-22FFEB16311D}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {B4577C85-CB83-462A-BCE3-22FFEB16311D}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {B4577C85-CB83-462A-BCE3-22FFEB16311D}.Development|Any CPU.ActiveCfg = Development|Any CPU
28 | {B4577C85-CB83-462A-BCE3-22FFEB16311D}.Development|Any CPU.Build.0 = Development|Any CPU
29 | EndGlobalSection
30 | GlobalSection(SolutionProperties) = preSolution
31 | HideSolutionNode = FALSE
32 | EndGlobalSection
33 | GlobalSection(NestedProjects) = preSolution
34 | EndGlobalSection
35 | GlobalSection(ExtensibilityGlobals) = postSolution
36 | SolutionGuid = {671B0BEC-2403-45B0-9357-2C97CC517668}
37 | EndGlobalSection
38 | GlobalSection(MonoDevelopProperties) = preSolution
39 | Policies = $0
40 | $0.TextStylePolicy = $1
41 | $1.EolMarker = Windows
42 | $1.inheritsSet = VisualStudio
43 | $1.inheritsScope = text/plain
44 | $1.scope = text/x-csharp
45 | $0.CSharpFormattingPolicy = $2
46 | $2.IndentSwitchSection = True
47 | $2.NewLinesForBracesInProperties = True
48 | $2.NewLinesForBracesInAccessors = True
49 | $2.NewLinesForBracesInAnonymousMethods = True
50 | $2.NewLinesForBracesInControlBlocks = True
51 | $2.NewLinesForBracesInAnonymousTypes = True
52 | $2.NewLinesForBracesInObjectCollectionArrayInitializers = True
53 | $2.NewLinesForBracesInLambdaExpressionBody = True
54 | $2.NewLineForElse = True
55 | $2.NewLineForCatch = True
56 | $2.NewLineForFinally = True
57 | $2.NewLineForMembersInObjectInit = True
58 | $2.NewLineForMembersInAnonymousTypes = True
59 | $2.NewLineForClausesInQuery = True
60 | $2.SpacingAfterMethodDeclarationName = False
61 | $2.SpaceAfterMethodCallName = False
62 | $2.SpaceBeforeOpenSquareBracket = False
63 | $2.inheritsSet = Mono
64 | $2.inheritsScope = text/x-csharp
65 | $2.scope = text/x-csharp
66 | EndGlobalSection
67 | GlobalSection(MonoDevelopProperties) = preSolution
68 | Policies = $0
69 | $0.TextStylePolicy = $1
70 | $1.EolMarker = Windows
71 | $1.inheritsSet = VisualStudio
72 | $1.inheritsScope = text/plain
73 | $1.scope = text/x-csharp
74 | $0.CSharpFormattingPolicy = $2
75 | $2.IndentSwitchSection = True
76 | $2.NewLinesForBracesInProperties = True
77 | $2.NewLinesForBracesInAccessors = True
78 | $2.NewLinesForBracesInAnonymousMethods = True
79 | $2.NewLinesForBracesInControlBlocks = True
80 | $2.NewLinesForBracesInAnonymousTypes = True
81 | $2.NewLinesForBracesInObjectCollectionArrayInitializers = True
82 | $2.NewLinesForBracesInLambdaExpressionBody = True
83 | $2.NewLineForElse = True
84 | $2.NewLineForCatch = True
85 | $2.NewLineForFinally = True
86 | $2.NewLineForMembersInObjectInit = True
87 | $2.NewLineForMembersInAnonymousTypes = True
88 | $2.NewLineForClausesInQuery = True
89 | $2.SpacingAfterMethodDeclarationName = False
90 | $2.SpaceAfterMethodCallName = False
91 | $2.SpaceBeforeOpenSquareBracket = False
92 | $2.inheritsSet = Mono
93 | $2.inheritsScope = text/x-csharp
94 | $2.scope = text/x-csharp
95 | EndGlobalSection
96 | EndGlobal
97 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Beatmaps/RushBeatmap.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using osu.Framework.Graphics;
7 | using osu.Framework.Graphics.Sprites;
8 | using osu.Game.Beatmaps;
9 | using osu.Game.Rulesets.Rush.Objects;
10 | using osuTK;
11 |
12 | namespace osu.Game.Rulesets.Rush.Beatmaps
13 | {
14 | public class RushBeatmap : Beatmap
15 | {
16 | public override IEnumerable GetStatistics()
17 | {
18 | int minions = HitObjects.Count(s => s is Minion);
19 | int starsheets = HitObjects.Count(s => s is StarSheet);
20 | int sawblades = HitObjects.Count(s => s is Sawblade);
21 | int dualhits = HitObjects.Count(s => s is DualHit);
22 | int minibosses = HitObjects.Count(s => s is MiniBoss);
23 | int hearts = HitObjects.Count(s => s is Heart);
24 |
25 | return new[]
26 | {
27 | new BeatmapStatistic
28 | {
29 | Name = @"Minion Count",
30 | Content = minions.ToString(),
31 | CreateIcon = () => createIcon(FontAwesome.Regular.Angry),
32 | },
33 | new BeatmapStatistic
34 | {
35 | Name = @"Star Sheet Count",
36 | Content = starsheets.ToString(),
37 | CreateIcon = () => createIcon(FontAwesome.Regular.Star),
38 | },
39 | new BeatmapStatistic
40 | {
41 | Name = @"Dual Hit Count",
42 | Content = dualhits.ToString(),
43 | CreateIcon = () => createIcon(FontAwesome.Solid.Cog),
44 | },
45 | new BeatmapStatistic
46 | {
47 | Name = @"Sawblade Count",
48 | Content = sawblades.ToString(),
49 | CreateIcon = () => createIcon(FontAwesome.Solid.Sun),
50 | },
51 | new BeatmapStatistic
52 | {
53 | Name = @"Miniboss Count",
54 | Content = minibosses.ToString(),
55 | CreateIcon = () => createIcon(FontAwesome.Solid.Mitten),
56 | },
57 | new BeatmapStatistic
58 | {
59 | Name = @"Heart Count",
60 | Content = hearts.ToString(),
61 | CreateIcon = () => createIcon(FontAwesome.Solid.Heart),
62 | }
63 | };
64 | }
65 |
66 | private static Drawable createIcon(IconUsage icon) => new SpriteIcon { Icon = icon, Scale = new Vector2(0.7f) };
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Beatmaps/RushBeatmapConverter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading;
8 | using osu.Game.Beatmaps;
9 | using osu.Game.Rulesets.Objects;
10 |
11 | namespace osu.Game.Rulesets.Rush.Beatmaps
12 | {
13 | ///
14 | /// Wraps and depending
15 | /// on whether the original beatmap contains a given tag. Once the lazer editor has been fleshed out enough
16 | /// to explicitly choose rulesets, this will be unnecessary.
17 | ///
18 | public class RushBeatmapConverter : IBeatmapConverter
19 | {
20 | public readonly IBeatmapConverter BackedConverter;
21 | public const string CRAFTED_TAG = "crafted";
22 |
23 | public RushBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
24 | {
25 | bool crafted = !string.IsNullOrEmpty(beatmap.Metadata.Tags)
26 | && beatmap.Metadata.Tags
27 | .Split(" ")
28 | .Any(tag => tag.Equals(CRAFTED_TAG, StringComparison.OrdinalIgnoreCase));
29 |
30 | BackedConverter = crafted
31 | ? (IBeatmapConverter)new RushCraftedBeatmapConverter(beatmap, ruleset)
32 | : new RushGeneratedBeatmapConverter(beatmap, ruleset);
33 | }
34 |
35 | public event Action> ObjectConverted
36 | {
37 | add => BackedConverter.ObjectConverted += value;
38 | remove => BackedConverter.ObjectConverted -= value;
39 | }
40 |
41 | public bool CanConvert() => BackedConverter.CanConvert();
42 | public IBeatmap Convert(CancellationToken cancellationToken = default) => BackedConverter.Convert(cancellationToken);
43 |
44 | public IBeatmap Beatmap => BackedConverter.Beatmap;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Configuration/FeverActivationMode.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | namespace osu.Game.Rulesets.Rush.Configuration
5 | {
6 | ///
7 | /// The activation mode of fever for gaining bonus score on hits.
8 | ///
9 | public enum FeverActivationMode
10 | {
11 | ///
12 | /// Automatically once the fever progress fills up.
13 | ///
14 | Automatic,
15 |
16 | ///
17 | /// Manually using the action.
18 | ///
19 | Manual,
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Configuration/RushRulesetConfigManager.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Configuration;
5 | using osu.Game.Rulesets.Configuration;
6 |
7 | namespace osu.Game.Rulesets.Rush.Configuration
8 | {
9 | public class RushRulesetConfigManager : RulesetConfigManager
10 | {
11 | public RushRulesetConfigManager(SettingsStore settings, RulesetInfo ruleset, int? variant = null)
12 | : base(settings, ruleset, variant)
13 | {
14 | }
15 |
16 | protected override void InitialiseDefaults()
17 | {
18 | base.InitialiseDefaults();
19 |
20 | SetDefault(RushRulesetSettings.FeverActivationMode, FeverActivationMode.Automatic);
21 | }
22 | }
23 |
24 | public enum RushRulesetSettings
25 | {
26 | FeverActivationMode
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Input/IKeyBindingTouchHandler.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osuTK;
5 |
6 | namespace osu.Game.Rulesets.Rush.Input
7 | {
8 | public interface IKeyBindingTouchHandler
9 | {
10 | RushActionTarget ActionTargetForTouchPosition(Vector2 screenSpaceTouchPos) => RushActionTarget.None;
11 | }
12 |
13 | public enum RushActionTarget
14 | {
15 | None,
16 | Ground,
17 | Air,
18 | Fever,
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Input/RushInputManager.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using System.ComponentModel;
6 | using osu.Framework.Extensions.ListExtensions;
7 | using osu.Framework.Input;
8 | using osu.Framework.Input.Bindings;
9 | using osu.Framework.Lists;
10 | using osu.Game.Rulesets.Rush.Objects;
11 | using osu.Game.Rulesets.Rush.Replays;
12 | using osu.Game.Rulesets.UI;
13 | using osuTK.Input;
14 |
15 | namespace osu.Game.Rulesets.Rush.Input
16 | {
17 | public partial class RushInputManager : RulesetInputManager
18 | {
19 | protected override bool MapMouseToLatestTouch => false;
20 | public new RushFramedReplayInputHandler ReplayInputHandler => (RushFramedReplayInputHandler)base.ReplayInputHandler;
21 |
22 | ///
23 | /// Retrieves all actions in a currenty pressed states.
24 | ///
25 | public SlimReadOnlyListWrapper PressedActions => KeyBindingContainer.PressedActions;
26 |
27 | public RushInputManager(RulesetInfo ruleset)
28 | : base(ruleset, 0, SimultaneousBindingMode.Unique)
29 | {
30 | }
31 |
32 | protected override MouseButtonEventManager CreateButtonEventManagerFor(MouseButton button)
33 | => new RushMouseEventManager(button, this);
34 |
35 | protected override TouchEventManager CreateButtonEventManagerFor(TouchSource source)
36 | => new RushTouchEventManager(source, this);
37 |
38 |
39 | private readonly Dictionary touchActionMap = new Dictionary();
40 |
41 | private readonly Dictionary actionsInUse = new Dictionary();
42 |
43 | private void updateActionsCache()
44 | {
45 | for (RushAction action = RushAction.GroundPrimary; action <= RushAction.Fever; ++action)
46 | actionsInUse[action] = false;
47 |
48 | foreach (var pressedAction in PressedActions)
49 | actionsInUse[pressedAction] = true;
50 | }
51 |
52 | private RushAction? tryGetGroundAction() => tryGetActionInRange(RushAction.GroundPrimary, RushAction.AirPrimary);
53 | private RushAction? tryGetAirAction() => tryGetActionInRange(RushAction.AirPrimary, RushAction.Fever);
54 | private RushAction? tryGetFeverAction()
55 | {
56 | actionsInUse.TryGetValue(RushAction.Fever, out var inUse);
57 |
58 | if (!inUse) return RushAction.Fever;
59 |
60 | return null;
61 | }
62 | private RushAction? tryGetActionInRange(RushAction lowerBound, RushAction upperBound)
63 | {
64 | for (RushAction a = lowerBound; a < upperBound; ++a)
65 | {
66 | actionsInUse.TryGetValue(a, out var inUse);
67 |
68 | if (!inUse) return a;
69 | }
70 |
71 | return null;
72 | }
73 |
74 | public bool TryPressTouchAction(TouchSource source, RushActionTarget action)
75 | {
76 | updateActionsCache();
77 | RushAction? convertedAction = action switch
78 | {
79 | RushActionTarget.Ground => tryGetGroundAction(),
80 | RushActionTarget.Air => tryGetAirAction(),
81 | RushActionTarget.Fever => tryGetFeverAction(),
82 | _ => null
83 | };
84 |
85 | if (convertedAction is null) return false;
86 |
87 | touchActionMap[source] = convertedAction.Value;
88 | KeyBindingContainer.TriggerPressed(convertedAction.Value);
89 |
90 | return true;
91 | }
92 |
93 | public void ReleaseTouchAction(TouchSource source)
94 | {
95 | if (!touchActionMap.TryGetValue(source, out var action)) return;
96 | // The action has already been released, maybe due to the same keyboard key being released before the touch releases.
97 | if (!PressedActions.Contains(action)) return;
98 |
99 | KeyBindingContainer.TriggerReleased(action);
100 | }
101 | }
102 |
103 | public enum RushAction
104 | {
105 | [Description("Ground (Primary)")]
106 | GroundPrimary = 0,
107 |
108 | [Description("Ground (Secondary)")]
109 | GroundSecondary = 1,
110 |
111 | [Description("Ground (Tertiary)")]
112 | GroundTertiary = 2,
113 |
114 | [Description("Ground (Quaternary)")]
115 | GroundQuaternary = 3,
116 |
117 | [Description("Air (Primary)")]
118 | AirPrimary = 4,
119 |
120 | [Description("Air (Secondary)")]
121 | AirSecondary = 5,
122 |
123 | [Description("Air (Tertiary)")]
124 | AirTertiary = 6,
125 |
126 | [Description("Air (Quaternary)")]
127 | AirQuaternary = 7,
128 |
129 | [Description("Activate fever")]
130 | Fever = 8,
131 | }
132 |
133 | public static class RushActionExtensions
134 | {
135 | public static bool IsLaneAction(this RushAction action) => action < RushAction.Fever;
136 |
137 | public static LanedHitLane Lane(this RushAction action) => action switch
138 | {
139 | RushAction.GroundPrimary => LanedHitLane.Ground,
140 | RushAction.GroundSecondary => LanedHitLane.Ground,
141 | RushAction.GroundTertiary => LanedHitLane.Ground,
142 | RushAction.GroundQuaternary => LanedHitLane.Ground,
143 | RushAction.AirPrimary => LanedHitLane.Air,
144 | RushAction.AirSecondary => LanedHitLane.Air,
145 | RushAction.AirTertiary => LanedHitLane.Air,
146 | RushAction.AirQuaternary => LanedHitLane.Air,
147 | _ => LanedHitLane.Ground
148 | };
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Input/RushMouseEventManager.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using osu.Framework.Graphics;
7 | using osu.Framework.Input;
8 | using osu.Framework.Input.States;
9 | using osuTK;
10 | using osuTK.Input;
11 |
12 | namespace osu.Game.Rulesets.Rush.Input
13 | {
14 | // Temporarily exists to be as a testing convenience, will remove be PR merge
15 | public class RushMouseEventManager : MouseButtonEventManager
16 | {
17 | public override bool EnableClick => true;
18 | public override bool EnableDrag => false;
19 | public override bool ChangeFocusOnClick => false;
20 |
21 | private readonly RushInputManager rushInputManager;
22 |
23 | public RushMouseEventManager(MouseButton source, RushInputManager inputManager)
24 | : base(source)
25 | {
26 | rushInputManager = inputManager;
27 | }
28 |
29 | private IKeyBindingTouchHandler touchHandler;
30 |
31 | protected override Drawable HandleButtonDown(InputState state, List targets)
32 | {
33 | var result = base.HandleButtonDown(state, targets);
34 | touchHandler = targets.FirstOrDefault(d => d is IKeyBindingTouchHandler) as IKeyBindingTouchHandler;
35 |
36 | if (touchHandler != null)
37 | rushInputManager.TryPressTouchAction((TouchSource)Button, touchHandler.ActionTargetForTouchPosition(MouseDownPosition ?? Vector2.Zero));
38 |
39 | return result;
40 | }
41 |
42 | protected override void HandleButtonUp(InputState state, List targets)
43 | {
44 | if (touchHandler != null)
45 | rushInputManager.ReleaseTouchAction((TouchSource)Button);
46 |
47 | touchHandler = null;
48 |
49 | base.HandleButtonUp(state, targets);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Input/RushTouchEventManager.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using osu.Framework.Graphics;
7 | using osu.Framework.Input;
8 | using osu.Framework.Input.States;
9 |
10 | namespace osu.Game.Rulesets.Rush.Input
11 | {
12 | public class RushTouchEventManager : TouchEventManager
13 | {
14 | private readonly RushInputManager rushInputManager;
15 |
16 | public RushTouchEventManager(TouchSource source, RushInputManager inputManager)
17 | : base(source)
18 | {
19 | rushInputManager = inputManager;
20 | }
21 |
22 | private IKeyBindingTouchHandler touchHandler;
23 |
24 | protected override Drawable HandleButtonDown(InputState state, List targets)
25 | {
26 | // This must be done first to ensure TouchDownPosition is set
27 | var result = base.HandleButtonDown(state, targets);
28 |
29 | touchHandler = targets.FirstOrDefault(d => d is IKeyBindingTouchHandler) as IKeyBindingTouchHandler;
30 |
31 | if (touchHandler != null)
32 | rushInputManager.TryPressTouchAction(Button, touchHandler.ActionTargetForTouchPosition(TouchDownPosition.Value));
33 |
34 | return result;
35 | }
36 |
37 | protected override void HandleButtonUp(InputState state, List targets)
38 | {
39 | if (touchHandler != null)
40 | rushInputManager.ReleaseTouchAction(Button);
41 |
42 | touchHandler = null;
43 | base.HandleButtonUp(state, targets);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Judgements/CollisionDamagingJudgement.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Scoring;
5 |
6 | namespace osu.Game.Rulesets.Rush.Judgements
7 | {
8 | ///
9 | /// A judgement that decreases the player health points when
10 | /// the player collides with the hit object without hitting it.
11 | ///
12 | public class CollisionDamagingJudgement : RushJudgement
13 | {
14 | protected override double HealthPointIncreaseFor(HitResult result, bool playerCollided) =>
15 | result == MinResult && playerCollided ? -10.0 : 0.0;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Judgements/HeartJudgement.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Scoring;
5 |
6 | namespace osu.Game.Rulesets.Rush.Judgements
7 | {
8 | public class HeartJudgement : RushJudgement
9 | {
10 | public override HitResult MaxResult => HitResult.SmallBonus;
11 |
12 | protected override double HealthPointIncreaseFor(HitResult result, bool collided) =>
13 | result == MinResult && !collided ? 0.0 : 50.0;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Judgements/RushFeverJudgement.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Scoring;
5 |
6 | namespace osu.Game.Rulesets.Rush.Judgements
7 | {
8 | public class RushFeverJudgement : RushJudgement
9 | {
10 | public override HitResult MaxResult => HitResult.LargeBonus;
11 |
12 | protected override double HealthPointIncreaseFor(HitResult result, bool collided) => 0;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Judgements/RushIgnoreJudgement.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Scoring;
5 |
6 | namespace osu.Game.Rulesets.Rush.Judgements
7 | {
8 | public class RushIgnoreJudgement : RushJudgement
9 | {
10 | public override HitResult MaxResult => HitResult.IgnoreHit;
11 |
12 | protected override double HealthPointIncreaseFor(HitResult result, bool playerCollided) => 0.0;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Judgements/RushJudgement.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using osu.Game.Rulesets.Judgements;
6 | using osu.Game.Rulesets.Scoring;
7 |
8 | namespace osu.Game.Rulesets.Rush.Judgements
9 | {
10 | public class RushJudgement : Judgement
11 | {
12 | public override HitResult MaxResult => HitResult.Great;
13 |
14 | ///
15 | /// Retrieves the numeric health point increase of a .
16 | ///
17 | /// The to find the numeric health points increase for.
18 | public double HealthPointIncreaseFor(RushJudgementResult result) => HealthPointIncreaseFor(result.Type, result.PlayerCollided);
19 |
20 | ///
21 | /// Retrieves the numeric health point increase of a and whether the player collided.
22 | ///
23 | /// The to find the numeric health points increase for.
24 | /// Whether the player collided with the corresponding hit object at the point of judgement.
25 | /// The numeric health points increase of and .
26 | protected virtual double HealthPointIncreaseFor(HitResult result, bool playerCollided) => 0.0;
27 |
28 | // Temporary measure to prevent crashes due to HealthDisplay using this method
29 | // No miss animation though.
30 | protected sealed override double HealthIncreaseFor(HitResult result) => 0.0;
31 | // protected sealed override double HealthIncreaseFor(HitResult result) => throw new NotSupportedException($"Use the Rush!-specific version: {nameof(HealthPointIncreaseFor)}");
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Judgements/RushJudgementResult.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Rush.Objects;
6 |
7 | namespace osu.Game.Rulesets.Rush.Judgements
8 | {
9 | public class RushJudgementResult : JudgementResult
10 | {
11 | ///
12 | /// The that was judged.
13 | ///
14 | public new RushHitObject HitObject => (RushHitObject)base.HitObject;
15 |
16 | ///
17 | /// The judgement which this applies for.
18 | ///
19 | public new RushJudgement Judgement => (RushJudgement)base.Judgement;
20 |
21 | ///
22 | /// The gathered amount of fever prior to this occurring.
23 | ///
24 | public float FeverProgressAtJudgement { get; set; }
25 |
26 | ///
27 | /// Whether the player has collided with the corresponding hit object at the point of judgement.
28 | ///
29 | public bool PlayerCollided;
30 |
31 | public RushJudgementResult(RushHitObject hitObject, RushJudgement judgement)
32 | : base(hitObject, judgement)
33 | {
34 | }
35 |
36 | public override string ToString() => $"{Type} (HP:{Judgement.HealthPointIncreaseFor(this)} {Judgement})";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Judgements/RushTickJudgement.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Scoring;
5 |
6 | namespace osu.Game.Rulesets.Rush.Judgements
7 | {
8 | public class RushTickJudgement : RushJudgement
9 | {
10 | public override HitResult MaxResult => HitResult.SmallTickHit;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Judgements/SawbladeJudgement.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Scoring;
5 |
6 | namespace osu.Game.Rulesets.Rush.Judgements
7 | {
8 | public class SawbladeJudgement : RushJudgement
9 | {
10 | protected override double HealthPointIncreaseFor(HitResult result, bool playerCollided)
11 | {
12 | if (playerCollided)
13 | return -20.0;
14 |
15 | return 0.0;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModAutoplay.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using osu.Game.Beatmaps;
6 | using osu.Game.Rulesets.Mods;
7 | using osu.Game.Rulesets.Rush.Replays;
8 |
9 | namespace osu.Game.Rulesets.Rush.Mods
10 | {
11 | public class RushModAutoplay : ModAutoplay
12 | {
13 | public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList mods)
14 | {
15 | return new ModReplayData(new RushAutoGenerator(beatmap).Generate(), new ModCreatedUser { Username = "Autoplay" });
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModCinema.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using osu.Game.Beatmaps;
6 | using osu.Game.Rulesets.Mods;
7 | using osu.Game.Rulesets.Rush.Objects;
8 | using osu.Game.Rulesets.Rush.Replays;
9 |
10 | namespace osu.Game.Rulesets.Rush.Mods
11 | {
12 | public class RushModCinema : ModCinema
13 | {
14 | public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList mods)
15 | {
16 | return new ModReplayData(new RushAutoGenerator(beatmap).Generate(), new ModCreatedUser { Username = "Autoplay" });
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModDaycore.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Mods;
5 |
6 | namespace osu.Game.Rulesets.Rush.Mods
7 | {
8 | public class RushModDaycore : ModDaycore
9 | {
10 | public override double ScoreMultiplier => 0.3;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModDoubleTime.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Mods;
5 |
6 | namespace osu.Game.Rulesets.Rush.Mods
7 | {
8 | public class RushModDoubleTime : ModDoubleTime
9 | {
10 | public override double ScoreMultiplier => 1.12;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModFlashlight.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Bindables;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Layout;
7 | using osu.Game.Configuration;
8 | using osu.Game.Rulesets.Mods;
9 | using osu.Game.Rulesets.Rush.Objects;
10 | using osu.Game.Rulesets.Rush.UI;
11 | using osu.Game.Rulesets.UI;
12 | using osuTK;
13 |
14 | namespace osu.Game.Rulesets.Rush.Mods
15 | {
16 | public partial class RushModFlashlight : ModFlashlight
17 | {
18 | public override double ScoreMultiplier => 1.12;
19 |
20 | public override float DefaultFlashlightSize => 330;
21 |
22 | [SettingSource("Flashlight size", "Multiplier applied to the default flashlight size.")]
23 | public override BindableFloat SizeMultiplier { get; } = new BindableFloat
24 | {
25 | MinValue = 0.5f,
26 | MaxValue = 1.5f,
27 | Default = 1f,
28 | Value = 1f,
29 | Precision = 0.1f
30 | };
31 |
32 | [SettingSource("Change size based on combo", "Decrease the flashlight size as combo increases.")]
33 | public override BindableBool ComboBasedSize { get; } = new BindableBool
34 | {
35 | Default = true,
36 | Value = true
37 | };
38 |
39 | protected override Flashlight CreateFlashlight() => new RushFlashlight(this, playfield);
40 |
41 | private RushPlayfield playfield;
42 |
43 | public override void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset)
44 | {
45 | playfield = (RushPlayfield)drawableRuleset.Playfield;
46 | base.ApplyToDrawableRuleset(drawableRuleset);
47 | }
48 |
49 | private partial class RushFlashlight : Flashlight
50 | {
51 | private readonly LayoutValue flashlightProperties = new LayoutValue(Invalidation.DrawSize);
52 |
53 | private readonly RushPlayfield rushPlayfield;
54 |
55 | public RushFlashlight(ModFlashlight modFlashlight, RushPlayfield rushPlayfield) : base(modFlashlight)
56 | {
57 | this.rushPlayfield = rushPlayfield;
58 | FlashlightSize = new Vector2(0, GetSize());
59 |
60 | AddLayout(flashlightProperties);
61 | }
62 |
63 | protected override void UpdateFlashlightSize(float size)
64 | {
65 | this.TransformTo(nameof(FlashlightSize), new Vector2(0, size), FLASHLIGHT_FADE_DURATION);
66 | }
67 |
68 | protected override string FragmentShader => "CircularFlashlight";
69 |
70 | protected override void Update()
71 | {
72 | base.Update();
73 |
74 | if (!flashlightProperties.IsValid)
75 | {
76 | var flashlightPosition = rushPlayfield.OverPlayerEffectsContainer.ToSpaceOfOtherDrawable(rushPlayfield.OverPlayerEffectsContainer.OriginPosition, this);
77 | flashlightPosition.X += RushPlayfield.HIT_TARGET_OFFSET;
78 | FlashlightPosition = flashlightPosition;
79 | flashlightProperties.Validate();
80 | }
81 | }
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModHalfTime.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Mods;
5 |
6 | namespace osu.Game.Rulesets.Rush.Mods
7 | {
8 | public class RushModHalfTime : ModHalfTime
9 | {
10 | public override double ScoreMultiplier => 0.3;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModNightcore.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Mods;
5 | using osu.Game.Rulesets.Rush.Objects;
6 |
7 | namespace osu.Game.Rulesets.Rush.Mods
8 | {
9 | public class RushModNightcore : ModNightcore
10 | {
11 | public override double ScoreMultiplier => 1.12;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModNoFail.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Mods;
5 |
6 | namespace osu.Game.Rulesets.Rush.Mods
7 | {
8 | public class RushModNoFail : ModNoFail
9 | {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModPerfect.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Mods;
5 |
6 | namespace osu.Game.Rulesets.Rush.Mods
7 | {
8 | public class RushModPerfect : ModPerfect
9 | {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Mods/RushModSuddenDeath.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Mods;
5 |
6 | namespace osu.Game.Rulesets.Rush.Mods
7 | {
8 | public class RushModSuddenDeath : ModSuddenDeath
9 | {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableDualHit.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Framework.Graphics.Containers;
6 | using osu.Framework.Input.Events;
7 | using osu.Game.Rulesets.Objects;
8 | using osu.Game.Rulesets.Objects.Drawables;
9 | using osu.Game.Rulesets.Rush.Input;
10 | using osu.Game.Rulesets.Rush.Objects.Drawables.Pieces;
11 |
12 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
13 | {
14 | public partial class DrawableDualHit : DrawableRushHitObject
15 | {
16 | private readonly Container airHitContainer;
17 | private readonly Container groundHitContainer;
18 | private readonly DualHitJoinPiece skinnedJoin;
19 |
20 | public DrawableDualHitPart Air => airHitContainer.Child;
21 | public DrawableDualHitPart Ground => groundHitContainer.Child;
22 |
23 | public override bool DisplayResult => false;
24 |
25 | public DrawableDualHit()
26 | : this(null)
27 | {
28 | }
29 |
30 | public DrawableDualHit(DualHit hitObject)
31 | : base(hitObject)
32 | {
33 | RelativeSizeAxes = Axes.Y;
34 | Height = 1f;
35 |
36 | AddRangeInternal(new Drawable[]
37 | {
38 | skinnedJoin = new DualHitJoinPiece(),
39 | airHitContainer = new Container { Anchor = Anchor.TopCentre },
40 | groundHitContainer = new Container { Anchor = Anchor.BottomCentre },
41 | });
42 | }
43 |
44 | protected override void AddNestedHitObject(DrawableHitObject hitObject)
45 | {
46 | base.AddNestedHitObject(hitObject);
47 |
48 | switch (hitObject)
49 | {
50 | case DrawableDualHitPart part:
51 | (part.HitObject.Lane == LanedHitLane.Air ? airHitContainer : groundHitContainer).Add(part);
52 | break;
53 | }
54 | }
55 |
56 | protected override void ClearNestedHitObjects()
57 | {
58 | base.ClearNestedHitObjects();
59 | airHitContainer.Clear(false);
60 | groundHitContainer.Clear(false);
61 | }
62 |
63 | protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
64 | {
65 | switch (hitObject)
66 | {
67 | case DualHitPart part:
68 | return new DrawableDualHitPart(part) { CheckHittable = CheckHittable };
69 | }
70 |
71 | return base.CreateNestedHitObject(hitObject);
72 | }
73 |
74 | protected override void UpdateInitialTransforms()
75 | {
76 | base.UpdateInitialTransforms();
77 |
78 | skinnedJoin.Show();
79 | }
80 |
81 | // Input are handled by the DualHit parts, since they still act like normal minions
82 | public override bool OnPressed(KeyBindingPressEvent e) => false;
83 |
84 | protected override void CheckForResult(bool userTriggered, double timeOffset)
85 | {
86 | if (AllJudged) return;
87 |
88 | // We can judge this object the instant the nested objects are judged
89 | if (Air.AllJudged && Ground.AllJudged)
90 | ApplyResult((Air.IsHit && Ground.IsHit) ? Result.Judgement.MaxResult : Result.Judgement.MinResult);
91 | }
92 |
93 | protected override void UpdateHitStateTransforms(ArmedState state)
94 | {
95 | const float animation_time = 300f;
96 |
97 | switch (state)
98 | {
99 | case ArmedState.Miss:
100 | this.FadeOut(animation_time);
101 | break;
102 |
103 | case ArmedState.Hit:
104 | skinnedJoin.Hide();
105 | this.FadeOut(animation_time);
106 | break;
107 | }
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableDualHitPart.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Extensions.Color4Extensions;
5 | using osu.Framework.Graphics;
6 | using osu.Game.Rulesets.Objects.Drawables;
7 | using osu.Game.Rulesets.Rush.Objects.Drawables.Pieces;
8 | using osu.Game.Rulesets.Rush.UI;
9 | using osuTK;
10 | using osuTK.Graphics;
11 |
12 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
13 | {
14 | public partial class DrawableDualHitPart : DrawableLanedHit
15 | {
16 | public override bool DisplayExplosion => true;
17 |
18 | public DrawableDualHitPart()
19 | : this(null)
20 | {
21 | }
22 |
23 | public DrawableDualHitPart(DualHitPart hitObject)
24 | : base(hitObject)
25 | {
26 | Size = new Vector2(RushPlayfield.HIT_TARGET_SIZE);
27 |
28 | AddInternal(new DualHitPartPiece());
29 | }
30 |
31 | public new bool UpdateResult(bool userTriggered) => base.UpdateResult(userTriggered);
32 |
33 | protected override void UpdateHitStateTransforms(ArmedState state)
34 | {
35 | const float animation_time = 300f;
36 |
37 | switch (state)
38 | {
39 | case ArmedState.Miss:
40 | this.FadeColour(Color4.DarkGray.Darken(0.9f), 100);
41 | break;
42 |
43 | case ArmedState.Hit:
44 | float travelY = 400f * (HitObject.Lane == LanedHitLane.Air ? -1 : 1);
45 |
46 | this.MoveToY(travelY, animation_time, Easing.Out);
47 | this.FadeOut(animation_time);
48 |
49 | break;
50 | }
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableFeverBonus.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using osu.Game.Rulesets.Judgements;
6 | using osu.Game.Rulesets.Scoring;
7 |
8 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
9 | {
10 | public partial class DrawableFeverBonus : DrawableRushHitObject
11 | {
12 | public override bool DisplayExplosion => false;
13 | public override bool DisplayResult => false;
14 |
15 | public DrawableFeverBonus()
16 | : this(null)
17 | {
18 | }
19 |
20 | public DrawableFeverBonus(FeverBonus hitObject)
21 | : base(hitObject)
22 | {
23 | }
24 |
25 | public new void ApplyResult(HitResult result)
26 | {
27 | if (!Result.HasResult)
28 | base.ApplyResult(result);
29 | }
30 |
31 | protected override void CheckForResult(bool userTriggered, double timeOffset)
32 | {
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableHeart.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Allocation;
5 | using osu.Framework.Graphics;
6 | using osu.Game.Rulesets.Rush.Objects.Drawables.Pieces;
7 | using osu.Game.Rulesets.Rush.UI;
8 | using osu.Game.Rulesets.Scoring;
9 | using osuTK;
10 |
11 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
12 | {
13 | public partial class DrawableHeart : DrawableLanedHit
14 | {
15 | [Resolved]
16 | private RushPlayfield playfield { get; set; }
17 |
18 | public override bool DisplayResult => false;
19 | public override bool DisplayExplosion => true;
20 | protected override float LifetimeEndDelay => 0f;
21 | protected override bool ExpireOnHit => false;
22 |
23 | public DrawableHeart()
24 | : this(null)
25 | {
26 | }
27 |
28 | public DrawableHeart(Heart hitObject)
29 | : base(hitObject)
30 | {
31 | Size = new Vector2(RushPlayfield.HIT_TARGET_SIZE * 2f);
32 |
33 | AddInternal(new ActionBeatSyncedContainer
34 | {
35 | Origin = Anchor.Centre,
36 | Anchor = Anchor.Centre,
37 | RelativeSizeAxes = Axes.Both,
38 | Size = new Vector2(0.4f),
39 | NewBeat = (b, t, e, a) => this.ScaleTo(1.5f).Then().ScaleTo(1f, t.BeatLength, Easing.Out),
40 | Child = new HeartPiece
41 | {
42 | RelativeSizeAxes = Axes.Both,
43 | }
44 | });
45 | }
46 |
47 | protected override void CheckForResult(bool userTriggered, double timeOffset)
48 | {
49 | if (AllJudged)
50 | return;
51 |
52 | var result = HitObject.HitWindows.ResultFor(timeOffset);
53 |
54 | if (userTriggered)
55 | {
56 | if (result != HitResult.None)
57 | ApplyResult(Result.Judgement.MaxResult);
58 |
59 | return;
60 | }
61 |
62 | // if we haven't passed the hitobject time, do nothing
63 | if (timeOffset < 0)
64 | return;
65 |
66 | // if we've passed the object and can longer hit it, miss
67 | if (result == HitResult.None)
68 | ApplyResult(Result.Judgement.MinResult);
69 |
70 | // else if we're still able to hit it, check if the player is in the correct lane
71 | else if (playfield.PlayerSprite.CollidesWith(HitObject))
72 | ApplyResult(Result.Judgement.MaxResult);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableLanedHit.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Diagnostics;
5 | using osu.Framework.Allocation;
6 | using osu.Framework.Bindables;
7 | using osu.Framework.Graphics;
8 | using osu.Framework.Input.Events;
9 | using osu.Game.Rulesets.Objects.Drawables;
10 | using osu.Game.Rulesets.Rush.Input;
11 | using osu.Game.Rulesets.Scoring;
12 | using osu.Game.Rulesets.UI.Scrolling;
13 | using osuTK.Graphics;
14 |
15 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
16 | {
17 | [Cached(typeof(IDrawableLanedHit))]
18 | public partial class DrawableLanedHit : DrawableRushHitObject, IDrawableLanedHit
19 | where TLanedHit : LanedHit
20 | {
21 | public virtual Color4 LaneAccentColour => HitObject.Lane == LanedHitLane.Air ? AIR_ACCENT_COLOUR : GROUND_ACCENT_COLOUR;
22 |
23 | public Anchor LaneAnchor => Direction.Value == ScrollingDirection.Left ? Anchor.CentreLeft : Anchor.CentreRight;
24 |
25 | public Anchor LeadingAnchor => Direction.Value == ScrollingDirection.Left ? Anchor.CentreLeft : Anchor.CentreRight;
26 |
27 | public Anchor TrailingAnchor => Direction.Value == ScrollingDirection.Left ? Anchor.CentreRight : Anchor.CentreLeft;
28 |
29 | public LanedHitLane Lane { get; set; }
30 |
31 | public DrawableLanedHit()
32 | : base(null)
33 | {
34 | }
35 |
36 | public DrawableLanedHit(TLanedHit hitObject)
37 | : base(hitObject)
38 | {
39 | }
40 |
41 | protected override void OnApply()
42 | {
43 | base.OnApply();
44 |
45 | Lane = HitObject.Lane;
46 | Anchor = LaneAnchor;
47 | AccentColour.Value = LaneAccentColour;
48 | }
49 |
50 | protected override void OnDirectionChanged(ValueChangedEvent e)
51 | {
52 | base.OnDirectionChanged(e);
53 |
54 | if (HitObject != null)
55 | Anchor = LaneAnchor;
56 | }
57 |
58 | public override bool OnPressed(KeyBindingPressEvent e)
59 | {
60 | if (!e.Action.IsLaneAction())
61 | return false;
62 |
63 | if (!LaneMatchesAction(e.Action) || AllJudged)
64 | return false;
65 |
66 | if (!CheckHittable(this))
67 | return false;
68 |
69 | return UpdateResult(true);
70 | }
71 |
72 | public virtual bool LaneMatchesAction(RushAction action) => action.Lane() == HitObject.Lane;
73 |
74 | protected override void CheckForResult(bool userTriggered, double timeOffset)
75 | {
76 | Debug.Assert(HitObject.HitWindows != null);
77 |
78 | if (!userTriggered)
79 | {
80 | if (!HitObject.HitWindows.CanBeHit(timeOffset))
81 | ApplyResult(Result.Judgement.MinResult);
82 | return;
83 | }
84 |
85 | var result = HitObject.HitWindows.ResultFor(timeOffset);
86 | if (result == HitResult.None)
87 | return;
88 |
89 | ApplyResult(result);
90 | }
91 |
92 | protected override void UpdateHitStateTransforms(ArmedState state)
93 | {
94 | base.UpdateHitStateTransforms(state);
95 |
96 | switch (state)
97 | {
98 | case ArmedState.Miss:
99 | AccentColour.Value = Color4.Gray;
100 | break;
101 | }
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableMiniBoss.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using System.Linq;
6 | using osu.Framework.Graphics;
7 | using osu.Framework.Graphics.Containers;
8 | using osu.Framework.Input.Events;
9 | using osu.Game.Rulesets.Objects;
10 | using osu.Game.Rulesets.Objects.Drawables;
11 | using osu.Game.Rulesets.Rush.Input;
12 | using osu.Game.Rulesets.Rush.Objects.Drawables.Pieces;
13 | using osu.Game.Rulesets.Scoring;
14 | using osuTK;
15 |
16 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
17 | {
18 | public partial class DrawableMiniBoss : DrawableRushHitObject
19 | {
20 | private const float base_sprite_scale = 1f;
21 | private const float target_sprite_scale = 1.1f;
22 |
23 | private readonly MiniBossPiece mainPiece;
24 |
25 | private readonly Container ticks;
26 |
27 | public event Action Attacked;
28 |
29 | public DrawableMiniBoss()
30 | : this(null)
31 | {
32 | }
33 |
34 | public DrawableMiniBoss(MiniBoss hitObject)
35 | : base(hitObject)
36 | {
37 | Origin = Anchor.Centre;
38 |
39 | AddRangeInternal(new Drawable[]
40 | {
41 | mainPiece = new MiniBossPiece()
42 | {
43 | Origin = Anchor.Centre,
44 | Anchor = Anchor.Centre
45 | },
46 | ticks = new Container { RelativeSizeAxes = Axes.Both }
47 | });
48 | }
49 |
50 | protected override void AddNestedHitObject(DrawableHitObject hitObject)
51 | {
52 | base.AddNestedHitObject(hitObject);
53 |
54 | switch (hitObject)
55 | {
56 | case DrawableMiniBossTick tick:
57 | ticks.Add(tick);
58 | break;
59 | }
60 | }
61 |
62 | protected override void ClearNestedHitObjects()
63 | {
64 | base.ClearNestedHitObjects();
65 | ticks.Clear(false);
66 | }
67 |
68 | protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
69 | {
70 | switch (hitObject)
71 | {
72 | case MiniBossTick tick:
73 | return new DrawableMiniBossTick(tick);
74 | }
75 |
76 | return base.CreateNestedHitObject(hitObject);
77 | }
78 |
79 | protected override void Update()
80 | {
81 | base.Update();
82 |
83 | float fraction = (float)(HitObject.StartTime - Clock.CurrentTime) / 500f;
84 | mainPiece.Y = (float)(Math.Sin(fraction * 2 * Math.PI) * 5f);
85 |
86 | X = Math.Max(0, X);
87 | }
88 |
89 | protected override void UpdateInitialTransforms()
90 | {
91 | mainPiece.Scale = new Vector2(base_sprite_scale);
92 | }
93 |
94 | public override bool OnPressed(KeyBindingPressEvent e) => e.Action.IsLaneAction() && UpdateResult(true);
95 |
96 | protected override void CheckForResult(bool userTriggered, double timeOffset)
97 | {
98 | if (Time.Current < HitObject.StartTime || AllJudged)
99 | return;
100 |
101 | if (userTriggered && timeOffset < 0)
102 | {
103 | var nextTick = ticks.FirstOrDefault(t => !t.IsHit);
104 | nextTick?.TriggerResult(nextTick.Result.Judgement.MaxResult);
105 |
106 | var numHits = ticks.Count(r => r.IsHit);
107 | var completion = (float)numHits / HitObject.RequiredHits;
108 |
109 | mainPiece.ScaleTo(base_sprite_scale + Math.Min(target_sprite_scale - base_sprite_scale, (target_sprite_scale - base_sprite_scale) * completion), 260, Easing.OutQuint);
110 |
111 | OnAttacked(this, timeOffset);
112 | }
113 | else if (!userTriggered && timeOffset >= 0)
114 | {
115 | int numHits = 0;
116 |
117 | foreach (var tick in ticks)
118 | {
119 | if (tick.IsHit)
120 | {
121 | numHits++;
122 | continue;
123 | }
124 |
125 | tick.TriggerResult(tick.Result.Judgement.MinResult);
126 | }
127 |
128 | var hitResult = numHits == HitObject.RequiredHits
129 | ? HitResult.Great
130 | : numHits > HitObject.RequiredHits / 2
131 | ? HitResult.Good
132 | : HitResult.Miss;
133 |
134 | ApplyResult(hitResult);
135 | }
136 | }
137 |
138 | protected override void UpdateHitStateTransforms(ArmedState state)
139 | {
140 | switch (state)
141 | {
142 | case ArmedState.Miss:
143 | this.FadeOut(300);
144 | break;
145 |
146 | case ArmedState.Hit:
147 | const float gravity_time = 300;
148 | const float gravity_travel_height = 500f;
149 |
150 | using (BeginAbsoluteSequence(Time.Current, true))
151 | {
152 | this.RotateTo(-180, gravity_time);
153 | this.MoveToY(-gravity_travel_height, gravity_time, Easing.Out);
154 | this.FadeOut(gravity_time);
155 | }
156 |
157 | break;
158 | }
159 | }
160 |
161 | protected virtual void OnAttacked(DrawableMiniBoss drawableMiniBoss, double timeOffset) => Attacked?.Invoke(drawableMiniBoss, timeOffset);
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableMiniBossTick.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Framework.Input.Events;
6 | using osu.Game.Rulesets.Rush.Input;
7 | using osu.Game.Rulesets.Scoring;
8 |
9 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
10 | {
11 | public partial class DrawableMiniBossTick : DrawableRushHitObject
12 | {
13 | public override bool DisplayResult => false;
14 |
15 | public DrawableMiniBossTick()
16 | : this(null)
17 | {
18 | }
19 |
20 | public DrawableMiniBossTick(MiniBossTick hitObject)
21 | : base(hitObject)
22 | {
23 | }
24 |
25 | protected override void UpdateInitialTransforms() => this.FadeOut();
26 |
27 | public void TriggerResult(HitResult type)
28 | {
29 | HitObject.StartTime = Time.Current;
30 | ApplyResult(type);
31 | }
32 |
33 | protected override void CheckForResult(bool userTriggered, double timeOffset)
34 | {
35 | }
36 |
37 | public override bool OnPressed(KeyBindingPressEvent e) => false;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableMinion.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using osu.Framework.Allocation;
6 | using osu.Framework.Extensions.Color4Extensions;
7 | using osu.Framework.Graphics;
8 | using osu.Game.Rulesets.Objects.Drawables;
9 | using osu.Game.Rulesets.Rush.Objects.Drawables.Pieces;
10 | using osu.Game.Rulesets.Rush.UI;
11 | using osuTK;
12 | using osuTK.Graphics;
13 |
14 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
15 | {
16 | public partial class DrawableMinion : DrawableLanedHit
17 | {
18 | protected virtual RushSkinComponents Component => RushSkinComponents.Minion;
19 |
20 | private readonly Drawable minionPiece;
21 |
22 | private readonly Random random = new Random();
23 |
24 | [Resolved]
25 | private RushPlayfield playfield { get; set; }
26 |
27 | public override bool DisplayExplosion => true;
28 |
29 | public DrawableMinion()
30 | : this(null)
31 | {
32 | }
33 |
34 | public DrawableMinion(Minion hitObject = null)
35 | : base(hitObject)
36 | {
37 | Size = new Vector2(RushPlayfield.HIT_TARGET_SIZE);
38 |
39 | AddInternal(minionPiece = new MinionPiece()
40 | {
41 | RelativeSizeAxes = Axes.Both
42 | });
43 | }
44 |
45 | protected override void Update()
46 | {
47 | base.Update();
48 |
49 | float fraction = (float)(HitObject.StartTime - Clock.CurrentTime) / 500f;
50 | minionPiece.Y = (float)(Math.Sin(fraction * 2 * Math.PI) * (HitObject.Lane == LanedHitLane.Air ? 5f : 3f));
51 | }
52 |
53 | protected override void UpdateHitStateTransforms(ArmedState state)
54 | {
55 | base.UpdateHitStateTransforms(state);
56 |
57 | switch (state)
58 | {
59 | case ArmedState.Miss:
60 | this.FadeColour(Color4.DarkGray.Darken(0.9f), 100);
61 | break;
62 |
63 | case ArmedState.Hit:
64 | const float gravity_time = 300;
65 | float randomness = -0.5f + (float)random.NextDouble();
66 | float rotation = -180 + randomness * 50f;
67 | float gravityTravelHeight = randomness * 50f + (HitObject.Lane == LanedHitLane.Air ? 500f : 400f);
68 |
69 | this.RotateTo(rotation, gravity_time);
70 | this.MoveToY(-gravityTravelHeight, gravity_time, Easing.Out)
71 | .Then()
72 | .MoveToY(gravityTravelHeight * 2, gravity_time * 2, Easing.In);
73 |
74 | this.FadeOut(300);
75 | break;
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableRushHitObject.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using JetBrains.Annotations;
6 | using osu.Framework.Allocation;
7 | using osu.Framework.Bindables;
8 | using osu.Framework.Graphics;
9 | using osu.Framework.Graphics.Containers;
10 | using osu.Framework.Graphics.Primitives;
11 | using osu.Framework.Input.Bindings;
12 | using osu.Framework.Input.Events;
13 | using osu.Game.Rulesets.Judgements;
14 | using osu.Game.Rulesets.Objects;
15 | using osu.Game.Rulesets.Objects.Drawables;
16 | using osu.Game.Rulesets.Rush.Input;
17 | using osu.Game.Rulesets.Rush.Judgements;
18 | using osu.Game.Rulesets.Rush.UI;
19 | using osu.Game.Rulesets.Rush.UI.Fever;
20 | using osu.Game.Rulesets.Scoring;
21 | using osu.Game.Rulesets.UI.Scrolling;
22 | using osuTK.Graphics;
23 |
24 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
25 | {
26 | public abstract partial class DrawableRushHitObject : DrawableHitObject, IKeyBindingHandler
27 | {
28 | public static readonly Color4 AIR_ACCENT_COLOUR = new Color4(0.35f, 0.75f, 1f, 1f);
29 | public static readonly Color4 GROUND_ACCENT_COLOUR = new Color4(1f, 0.4f, 1f, 1f);
30 | public static readonly float LIFETIME_END_DELAY = 500f;
31 |
32 | public Func CheckHittable;
33 |
34 | protected readonly IBindable Direction = new Bindable();
35 |
36 | protected override bool ComputeIsMaskedAway(RectangleF maskingBounds) => false;
37 |
38 | protected RushInputManager ActionInputManager => (RushInputManager)GetContainingInputManager();
39 |
40 | ///
41 | /// Whether to display an explosion when this hit object is hit.
42 | ///
43 | public virtual bool DisplayExplosion => false;
44 |
45 | protected virtual bool ExpireOnHit => true;
46 | protected virtual bool ExpireOnMiss => false;
47 | protected virtual float LifetimeEndDelay => LIFETIME_END_DELAY;
48 |
49 | [Resolved]
50 | private DrawableRushRuleset drawableRuleset { get; set; }
51 |
52 | [Resolved]
53 | private FeverProcessor feverProcessor { get; set; }
54 |
55 | private readonly Container feverBonusContainer;
56 |
57 | protected DrawableRushHitObject(RushHitObject hitObject)
58 | : base(hitObject)
59 | {
60 | AddInternal(feverBonusContainer = new Container());
61 | }
62 |
63 | [BackgroundDependencyLoader(true)]
64 | private void load([NotNull] IScrollingInfo scrollingInfo)
65 | {
66 | Direction.BindTo(scrollingInfo.Direction);
67 | Direction.BindValueChanged(OnDirectionChanged, true);
68 | }
69 |
70 | protected virtual void OnDirectionChanged(ValueChangedEvent e)
71 | {
72 | Origin = Anchor.Centre;
73 | Anchor = e.NewValue == ScrollingDirection.Left ? Anchor.CentreLeft : Anchor.CentreRight;
74 | }
75 |
76 | protected override void CheckForResult(bool userTriggered, double timeOffset)
77 | {
78 | if (timeOffset >= 0)
79 | ApplyResult(Result.Judgement.MaxResult);
80 | }
81 |
82 | public virtual bool OnPressed(KeyBindingPressEvent e) => false;
83 |
84 | public virtual void OnReleased(KeyBindingReleaseEvent e)
85 | {
86 | }
87 |
88 | protected override void UpdateHitStateTransforms(ArmedState state)
89 | {
90 | switch (state)
91 | {
92 | case ArmedState.Miss:
93 | AccentColour.Value = Color4.Gray;
94 |
95 | if (!ExpireOnMiss)
96 | LifetimeEnd = HitObject.GetEndTime() + LifetimeEndDelay;
97 |
98 | break;
99 |
100 | case ArmedState.Hit:
101 | if (!ExpireOnHit)
102 | LifetimeEnd = HitObject.GetEndTime() + LifetimeEndDelay;
103 |
104 | break;
105 | }
106 | }
107 |
108 | protected override JudgementResult CreateResult(Judgement judgement) => new RushJudgementResult(HitObject, (RushJudgement)judgement);
109 |
110 | protected new void ApplyResult(HitResult result)
111 | {
112 | // This is the only point to correctly apply values to the judgement
113 | // result in correct time, check whether the player collided now.
114 | var r = (RushJudgementResult)Result;
115 | r.PlayerCollided = drawableRuleset.PlayerCollidesWith(r.HitObject);
116 |
117 | base.ApplyResult(result);
118 |
119 | foreach (var bonus in feverBonusContainer)
120 | {
121 | bool eligible = IsHit && feverProcessor.InFeverMode.Value;
122 | bonus.ApplyResult(eligible ? bonus.Result.Judgement.MaxResult : bonus.Result.Judgement.MinResult);
123 | }
124 | }
125 |
126 | protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
127 | {
128 | if (hitObject is FeverBonus x)
129 | return new DrawableFeverBonus(x);
130 |
131 | return base.CreateNestedHitObject(hitObject);
132 | }
133 |
134 | protected override void AddNestedHitObject(DrawableHitObject hitObject)
135 | {
136 | if (hitObject is DrawableFeverBonus x)
137 | feverBonusContainer.Add(x);
138 |
139 | base.AddNestedHitObject(hitObject);
140 | }
141 |
142 | protected override void ClearNestedHitObjects()
143 | {
144 | feverBonusContainer.Clear(false);
145 | base.ClearNestedHitObjects();
146 | }
147 | }
148 |
149 | public abstract partial class DrawableRushHitObject : DrawableRushHitObject
150 | where TObject : RushHitObject
151 | {
152 | public new TObject HitObject => (TObject)base.HitObject;
153 |
154 | protected DrawableRushHitObject(TObject hitObject)
155 | : base(hitObject)
156 | {
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableRushJudgement.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Game.Rulesets.Judgements;
6 | using osuTK;
7 |
8 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
9 | {
10 | public partial class DrawableRushJudgement : DrawableJudgement
11 | {
12 | private const float judgement_time = 250f;
13 | private const float judgement_movement = 300;
14 |
15 | public DrawableRushJudgement()
16 | {
17 | Anchor = Anchor.Centre;
18 | Origin = Anchor.Centre;
19 | Position = new Vector2(0f, -80f);
20 | Scale = new Vector2(1.5f);
21 | }
22 |
23 | protected override void ApplyHitAnimations() =>
24 | this.ScaleTo(1f, judgement_time)
25 | .Then()
26 | .MoveToOffset(new Vector2(-judgement_movement, 0f), judgement_time, Easing.In)
27 | .Expire();
28 |
29 | protected override void ApplyMissAnimations() =>
30 | this.ScaleTo(1f, judgement_time)
31 | .Then()
32 | .MoveToOffset(new Vector2(-judgement_movement, 0f), judgement_time, Easing.In)
33 | .Expire();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableSawblade.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Allocation;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Graphics.Containers;
7 | using osu.Framework.Input.Events;
8 | using osu.Game.Rulesets.Rush.Input;
9 | using osu.Game.Rulesets.Rush.Objects.Drawables.Pieces;
10 | using osu.Game.Rulesets.Rush.UI;
11 | using osu.Game.Rulesets.Scoring;
12 | using osuTK;
13 | using osuTK.Graphics;
14 |
15 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
16 | {
17 | public partial class DrawableSawblade : DrawableLanedHit
18 | {
19 | [Resolved]
20 | private RushPlayfield playfield { get; set; }
21 |
22 | // Sawblade uses the reverse lane colour to indicate which key the player should tap to avoid it
23 | public override Color4 LaneAccentColour => HitObject.Lane == LanedHitLane.Ground ? AIR_ACCENT_COLOUR : GROUND_ACCENT_COLOUR;
24 |
25 | protected override bool ExpireOnHit => false;
26 | protected override bool ExpireOnMiss => false;
27 |
28 | private readonly Container sawbladeContainer;
29 | private readonly Drawable sawblade;
30 |
31 | public DrawableSawblade()
32 | : this(null)
33 | {
34 | }
35 |
36 | public DrawableSawblade(Sawblade hitObject)
37 | : base(hitObject)
38 | {
39 | Size = new Vector2(RushPlayfield.HIT_TARGET_SIZE * 2f);
40 |
41 | AddRangeInternal(new[]
42 | {
43 | sawbladeContainer = new Container
44 | {
45 | Origin = Anchor.Centre,
46 | Anchor = Anchor.Centre,
47 | RelativeSizeAxes = Axes.Both,
48 | Size = new Vector2(0.8f),
49 | Child = sawblade = new SawbladePiece()
50 | {
51 | Origin = Anchor.Centre,
52 | RelativeSizeAxes = Axes.Both,
53 | Size = new Vector2(0.8f)
54 | }
55 | }
56 | });
57 | }
58 |
59 | protected override void OnApply()
60 | {
61 | base.OnApply();
62 |
63 | sawbladeContainer.Masking = HitObject.Lane == LanedHitLane.Ground;
64 | sawblade.Anchor = HitObject.Lane == LanedHitLane.Ground ? Anchor.BottomCentre : Anchor.TopCentre;
65 | }
66 |
67 | // Sawblade doesn't handle user presses at all.
68 | public override bool OnPressed(KeyBindingPressEvent e) => false;
69 |
70 | protected override void CheckForResult(bool userTriggered, double timeOffset)
71 | {
72 | // sawblades can't be user triggered, and will not hurt the player in the leading hit windows
73 | if (userTriggered || timeOffset < 0 || AllJudged)
74 | return;
75 |
76 | switch (HitObject.HitWindows.ResultFor(timeOffset))
77 | {
78 | case HitResult.None:
79 | // if we've reached the trailing "none", we successfully dodged the sawblade
80 | ApplyResult(Result.Judgement.MaxResult);
81 | break;
82 |
83 | case HitResult.Miss:
84 | // sawblades only hurt the player if they collide within the trailing "miss" hit window
85 | if (playfield.PlayerSprite.CollidesWith(HitObject))
86 | ApplyResult(Result.Judgement.MinResult);
87 |
88 | break;
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableStarSheetCap.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Bindables;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Input.Events;
7 | using osu.Game.Rulesets.Objects.Drawables;
8 | using osu.Game.Rulesets.Rush.Input;
9 | using osu.Game.Rulesets.Rush.Objects.Drawables.Pieces;
10 | using osu.Game.Rulesets.UI.Scrolling;
11 | using osuTK;
12 |
13 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
14 | {
15 | public abstract partial class DrawableStarSheetCap : DrawableLanedHit
16 | where TObject : LanedHit
17 | {
18 | protected abstract RushSkinComponents Component { get; }
19 |
20 | protected DrawableStarSheet StarSheet => (DrawableStarSheet)ParentHitObject;
21 |
22 | protected abstract Anchor CapAnchor { get; }
23 |
24 | public override bool DisplayExplosion => true;
25 |
26 | protected DrawableStarSheetCap(TObject hitObject)
27 | : base(hitObject)
28 | {
29 | Size = new Vector2(DrawableStarSheet.NOTE_SHEET_SIZE * 1.1f);
30 | Origin = Anchor.Centre;
31 |
32 | AddInternal(new StarSheetCapStarPiece()
33 | {
34 | Origin = Anchor.Centre,
35 | Anchor = Anchor.Centre,
36 | //RelativeSizeAxes = Axes.Both,
37 | });
38 | }
39 |
40 | protected override void OnApply()
41 | {
42 | base.OnApply();
43 |
44 | Anchor = CapAnchor;
45 | AccentColour.BindTo(StarSheet.AccentColour);
46 | }
47 |
48 | protected override void OnFree()
49 | {
50 | base.OnFree();
51 | AccentColour.UnbindFrom(StarSheet.AccentColour);
52 | }
53 |
54 | protected override void UpdateStartTimeStateTransforms()
55 | {
56 | Scale = Vector2.One;
57 | Alpha = 1f;
58 | }
59 |
60 | protected override void UpdateHitStateTransforms(ArmedState state)
61 | {
62 | base.UpdateHitStateTransforms(state);
63 |
64 | if (state == ArmedState.Hit)
65 | Hide();
66 | }
67 |
68 | public bool TriggerResult() => UpdateResult(true);
69 |
70 | protected override void OnDirectionChanged(ValueChangedEvent e) => Anchor = CapAnchor;
71 |
72 | public override bool OnPressed(KeyBindingPressEvent e) => false; // Handled by the star sheet object itself.
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableStarSheetHead.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using osu.Framework.Graphics;
6 | using osu.Game.Rulesets.Objects.Drawables;
7 | using osu.Game.Rulesets.Scoring;
8 |
9 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
10 | {
11 | public partial class DrawableStarSheetHead : DrawableStarSheetCap
12 | {
13 | protected override RushSkinComponents Component => RushSkinComponents.StarSheetHead;
14 |
15 | protected override Anchor CapAnchor => LeadingAnchor;
16 |
17 | public DrawableStarSheetHead()
18 | : this(null)
19 | {
20 | }
21 |
22 | public DrawableStarSheetHead(StarSheetHead starSheetHead)
23 | : base(starSheetHead)
24 | {
25 | }
26 |
27 | protected override void CheckForResult(bool userTriggered, double timeOffset)
28 | {
29 | if (userTriggered)
30 | {
31 | var result = HitObject.HitWindows.ResultFor(timeOffset);
32 | if (result == HitResult.None)
33 | return;
34 |
35 | ApplyResult(result);
36 | }
37 | else if (!HitObject.HitWindows.CanBeHit(timeOffset))
38 | {
39 | ApplyResult(Result.Judgement.MinResult);
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/DrawableStarSheetTail.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Game.Rulesets.Scoring;
6 |
7 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
8 | {
9 | public partial class DrawableStarSheetTail : DrawableStarSheetCap
10 | {
11 | protected override RushSkinComponents Component => RushSkinComponents.StarSheetTail;
12 |
13 | // FIXME: should logically be TrailingAnchor, not sure why it renders incorrectly
14 | protected override Anchor CapAnchor => LeadingAnchor;
15 |
16 | public DrawableStarSheetTail()
17 | : this(null)
18 | {
19 | }
20 |
21 | public DrawableStarSheetTail(StarSheetTail starSheetTail)
22 | : base(starSheetTail)
23 | {
24 | }
25 |
26 | protected override void CheckForResult(bool userTriggered, double timeOffset)
27 | {
28 | var overallMissed = StarSheet.Result.Type == StarSheet.Result.Judgement.MinResult;
29 |
30 | // Apply tail miss at its time when the entire star sheet has already been judged as missed.
31 | if (overallMissed && timeOffset >= 0)
32 | {
33 | ApplyResult(Result.Judgement.MinResult);
34 | return;
35 | }
36 |
37 | // for now let's give the player an automatic perfect if they hold the action (like in a certain other rhythm game)
38 | if (!userTriggered)
39 | {
40 | if (timeOffset >= 0)
41 | ApplyResult(Result.Judgement.MaxResult);
42 | return;
43 | }
44 |
45 | var result = HitObject.HitWindows.ResultFor(timeOffset);
46 | if (result == HitResult.None)
47 | return;
48 |
49 | // ...and an automatic perfect if they release within any "hit" judged period
50 | ApplyResult(Result.Judgement.MaxResult);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/IDrawableLanedHit.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osuTK.Graphics;
6 |
7 | namespace osu.Game.Rulesets.Rush.Objects.Drawables
8 | {
9 | public interface IDrawableLanedHit
10 | {
11 | LanedHitLane Lane { get; set; }
12 | Anchor LaneAnchor { get; }
13 | Color4 LaneAccentColour { get; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/Pieces/DualHitJoinPiece.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Framework.Graphics.Colour;
6 | using osu.Framework.Graphics.Shapes;
7 | using osuTK;
8 |
9 | namespace osu.Game.Rulesets.Rush.Objects.Drawables.Pieces
10 | {
11 | public partial class DualHitJoinPiece : Box
12 | {
13 | public DualHitJoinPiece()
14 | {
15 | Anchor = Anchor.Centre;
16 | Origin = Anchor.Centre;
17 | RelativeSizeAxes = Axes.Y;
18 | Size = new Vector2(10f, 1f);
19 | Colour = ColourInfo.GradientVertical(DrawableRushHitObject.AIR_ACCENT_COLOUR, DrawableRushHitObject.GROUND_ACCENT_COLOUR);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/Pieces/DualHitPartPiece.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using JetBrains.Annotations;
5 | using osu.Framework.Allocation;
6 | using osu.Framework.Bindables;
7 | using osu.Framework.Extensions.Color4Extensions;
8 | using osu.Framework.Graphics;
9 | using osu.Framework.Graphics.Containers;
10 | using osu.Framework.Graphics.Shapes;
11 | using osu.Framework.Graphics.Sprites;
12 | using osu.Game.Graphics.Backgrounds;
13 | using osu.Game.Rulesets.Objects.Drawables;
14 | using osu.Game.Rulesets.Rush.UI;
15 | using osuTK;
16 | using osuTK.Graphics;
17 |
18 | namespace osu.Game.Rulesets.Rush.Objects.Drawables.Pieces
19 | {
20 | public partial class DualHitPartPiece : CompositeDrawable
21 | {
22 | private const double rotation_time = 1000;
23 |
24 | private readonly SpriteIcon gearSpriteIcon;
25 | private readonly Box background;
26 | private readonly Triangles triangles;
27 |
28 | public readonly Bindable AccentColour = new Bindable();
29 |
30 | public DualHitPartPiece()
31 | {
32 | Size = new Vector2(RushPlayfield.HIT_TARGET_SIZE);
33 |
34 | AddRangeInternal(new Drawable[]
35 | {
36 | gearSpriteIcon = new SpriteIcon
37 | {
38 | Origin = Anchor.Centre,
39 | Anchor = Anchor.Centre,
40 | RelativeSizeAxes = Axes.Both,
41 | Icon = FontAwesome.Solid.Cog
42 | },
43 | new CircularContainer
44 | {
45 | Origin = Anchor.Centre,
46 | Anchor = Anchor.Centre,
47 | RelativeSizeAxes = Axes.Both,
48 | Scale = new Vector2(0.7f),
49 | BorderThickness = RushPlayfield.HIT_TARGET_SIZE * 0.1f,
50 | BorderColour = Color4.White,
51 | Masking = true,
52 | Children = new Drawable[]
53 | {
54 | background = new Box { RelativeSizeAxes = Axes.Both },
55 | triangles = new Triangles { RelativeSizeAxes = Axes.Both }
56 | }
57 | },
58 | });
59 | }
60 |
61 | [BackgroundDependencyLoader]
62 | private void load([CanBeNull] DrawableHitObject drawableHitObject)
63 | {
64 | if (drawableHitObject != null)
65 | AccentColour.BindTo(drawableHitObject.AccentColour);
66 |
67 | AccentColour.BindValueChanged(evt =>
68 | {
69 | background.Colour = evt.NewValue.Darken(0.5f);
70 | triangles.Colour = evt.NewValue;
71 | triangles.Alpha = 0.8f;
72 | gearSpriteIcon.Colour = evt.NewValue.Lighten(0.5f);
73 | });
74 | }
75 |
76 | protected override void Update()
77 | {
78 | base.Update();
79 |
80 | gearSpriteIcon.Rotation = (float)(Time.Current % rotation_time / rotation_time) * 360f;
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/Pieces/HeartPiece.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Framework.Graphics.Pooling;
6 | using osu.Framework.Graphics.Sprites;
7 | using osuTK;
8 | using osuTK.Graphics;
9 |
10 | namespace osu.Game.Rulesets.Rush.Objects.Drawables.Pieces
11 | {
12 | public partial class HeartPiece : PoolableDrawable
13 | {
14 | public HeartPiece()
15 | {
16 | Origin = Anchor.Centre;
17 | Anchor = Anchor.Centre;
18 |
19 | InternalChildren = new Drawable[]
20 | {
21 | new SpriteIcon
22 | {
23 | Origin = Anchor.Centre,
24 | Anchor = Anchor.Centre,
25 | RelativeSizeAxes = Axes.Both,
26 | FillMode = FillMode.Fit,
27 | Icon = FontAwesome.Solid.Heart,
28 | Colour = Color4.HotPink,
29 | },
30 | new SpriteIcon
31 | {
32 | Origin = Anchor.Centre,
33 | Anchor = Anchor.Centre,
34 | RelativeSizeAxes = Axes.Both,
35 | FillMode = FillMode.Fit,
36 | Icon = FontAwesome.Solid.Heart,
37 | Size = new Vector2(0.8f),
38 | Colour = Color4.Red
39 | }
40 | };
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/Pieces/MiniBossPiece.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Allocation;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Graphics.Animations;
7 | using osu.Framework.Graphics.Containers;
8 | using osu.Framework.Graphics.Textures;
9 |
10 | namespace osu.Game.Rulesets.Rush.Objects.Drawables.Pieces
11 | {
12 | public partial class MiniBossPiece : CompositeDrawable
13 | {
14 | private readonly TextureAnimation normalAnimation;
15 | private readonly TextureAnimation hitAnimation;
16 |
17 | public MiniBossPiece()
18 | {
19 | Origin = Anchor.Centre;
20 | Anchor = Anchor.Centre;
21 |
22 | AddRangeInternal(new Drawable[]
23 | {
24 | normalAnimation = new TextureAnimation
25 | {
26 | Origin = Anchor.Centre,
27 | Anchor = Anchor.Centre,
28 | DefaultFrameLength = 250,
29 | },
30 | hitAnimation = new TextureAnimation
31 | {
32 | Origin = Anchor.Centre,
33 | Anchor = Anchor.Centre,
34 | DefaultFrameLength = 250,
35 | Alpha = 0f
36 | },
37 | });
38 | }
39 |
40 | [BackgroundDependencyLoader]
41 | private void load(TextureStore store)
42 | {
43 | normalAnimation.AddFrames(new[] { store.Get("MiniBoss/pippidon_boss_0"), store.Get("MiniBoss/pippidon_boss_1") });
44 | hitAnimation.AddFrames(new[] { store.Get("MiniBoss/pippidon_boss_hurt_0"), store.Get("MiniBoss/pippidon_boss_hurt_1"), store.Get("MiniBoss/pippidon_boss_hurt_2") });
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/Pieces/MinionPiece.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Allocation;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Graphics.Animations;
7 | using osu.Framework.Graphics.Containers;
8 | using osu.Framework.Graphics.Textures;
9 |
10 | namespace osu.Game.Rulesets.Rush.Objects.Drawables.Pieces
11 | {
12 | public partial class MinionPiece : CompositeDrawable
13 | {
14 | private readonly TextureAnimation animation;
15 |
16 | public MinionPiece()
17 | {
18 | RelativeSizeAxes = Axes.Both;
19 |
20 | InternalChild = animation = new TextureAnimation
21 | {
22 | Origin = Anchor.Centre,
23 | Anchor = Anchor.Centre,
24 | FillMode = FillMode.Fit,
25 | RelativeSizeAxes = Axes.Both,
26 | DefaultFrameLength = 250,
27 | };
28 | }
29 |
30 | [BackgroundDependencyLoader(true)]
31 | private void load(IDrawableLanedHit laned, TextureStore textures)
32 | {
33 | var laneStr = laned.Lane == LanedHitLane.Air ? "air" : "ground";
34 |
35 | animation.AddFrames(new[] { textures.Get($"Minion/pippidon_{laneStr}_0"), textures.Get($"Minion/pippidon_{laneStr}_1") });
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/Pieces/SawbladePiece.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using JetBrains.Annotations;
5 | using osu.Framework.Allocation;
6 | using osu.Framework.Bindables;
7 | using osu.Framework.Extensions.Color4Extensions;
8 | using osu.Framework.Graphics;
9 | using osu.Framework.Graphics.Containers;
10 | using osu.Framework.Graphics.Shapes;
11 | using osu.Framework.Graphics.Sprites;
12 | using osu.Game.Graphics.Backgrounds;
13 | using osu.Game.Rulesets.Objects.Drawables;
14 | using osuTK;
15 | using osuTK.Graphics;
16 |
17 | namespace osu.Game.Rulesets.Rush.Objects.Drawables.Pieces
18 | {
19 | public partial class SawbladePiece : CompositeDrawable
20 | {
21 | private const double rotation_time = 1000;
22 |
23 | private readonly SpriteIcon outerSawIcon;
24 | private readonly SpriteIcon innerSawIcon;
25 | private readonly Box backgroundBox;
26 | private readonly Triangles triangles;
27 |
28 | public readonly Bindable AccentColour = new Bindable();
29 |
30 | public SawbladePiece()
31 | {
32 | Origin = Anchor.Centre;
33 | Anchor = Anchor.Centre;
34 | RelativeSizeAxes = Axes.Both;
35 |
36 | InternalChildren = new Drawable[]
37 | {
38 | outerSawIcon = new SpriteIcon
39 | {
40 | Origin = Anchor.Centre,
41 | Anchor = Anchor.Centre,
42 | Icon = FontAwesome.Solid.Sun,
43 | Colour = Color4.White,
44 | RelativeSizeAxes = Axes.Both,
45 | Size = new Vector2(1.1f)
46 | },
47 | innerSawIcon = new SpriteIcon
48 | {
49 | Origin = Anchor.Centre,
50 | Anchor = Anchor.Centre,
51 | Icon = FontAwesome.Solid.Sun,
52 | RelativeSizeAxes = Axes.Both,
53 | },
54 | new CircularContainer
55 | {
56 | Anchor = Anchor.Centre,
57 | Origin = Anchor.Centre,
58 | RelativeSizeAxes = Axes.Both,
59 | BorderThickness = DrawableStarSheet.NOTE_SHEET_SIZE * 0.1f,
60 | BorderColour = Color4.White,
61 | Masking = true,
62 | Size = new Vector2(0.75f),
63 | Children = new Drawable[]
64 | {
65 | backgroundBox = new Box { RelativeSizeAxes = Axes.Both },
66 | triangles = new Triangles { RelativeSizeAxes = Axes.Both }
67 | }
68 | }
69 | };
70 | }
71 |
72 | [BackgroundDependencyLoader(true)]
73 | private void load([CanBeNull] DrawableHitObject drawableHitObject)
74 | {
75 | if (drawableHitObject != null)
76 | AccentColour.BindTo(drawableHitObject.AccentColour);
77 |
78 | AccentColour.BindValueChanged(evt =>
79 | {
80 | backgroundBox.Colour = evt.NewValue.Darken(0.5f);
81 | triangles.Colour = evt.NewValue;
82 | triangles.Alpha = 0.8f;
83 | innerSawIcon.Colour = evt.NewValue.Lighten(0.5f);
84 | }, true);
85 | }
86 |
87 | protected override void Update()
88 | {
89 | base.Update();
90 |
91 | innerSawIcon.Rotation = outerSawIcon.Rotation = (float)(Time.Current % rotation_time / rotation_time) * 360f;
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/Pieces/StarSheetBodyPiece.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using JetBrains.Annotations;
5 | using osu.Framework.Allocation;
6 | using osu.Framework.Bindables;
7 | using osu.Framework.Extensions.Color4Extensions;
8 | using osu.Framework.Graphics;
9 | using osu.Framework.Graphics.Containers;
10 | using osu.Framework.Graphics.Shapes;
11 | using osu.Game.Graphics.Backgrounds;
12 | using osu.Game.Rulesets.Objects.Drawables;
13 | using osuTK.Graphics;
14 |
15 | namespace osu.Game.Rulesets.Rush.Objects.Drawables.Pieces
16 | {
17 | public partial class StarSheetBodyPiece : CompositeDrawable
18 | {
19 | private const float border_size = 1f / 8f;
20 |
21 | private readonly Box backgroundBox, topBox, bottomBox;
22 | private readonly Triangles triangles;
23 |
24 | public readonly Bindable AccentColour = new Bindable();
25 |
26 | public StarSheetBodyPiece()
27 | {
28 | RelativeSizeAxes = Axes.Y;
29 |
30 | InternalChildren = new Drawable[]
31 | {
32 | backgroundBox = new Box { RelativeSizeAxes = Axes.Both },
33 | triangles = new Triangles { RelativeSizeAxes = Axes.Both },
34 | topBox = new Box
35 | {
36 | RelativeSizeAxes = Axes.Both,
37 | Height = border_size,
38 | Origin = Anchor.TopCentre,
39 | Anchor = Anchor.TopCentre,
40 | },
41 | bottomBox = new Box
42 | {
43 | RelativeSizeAxes = Axes.Both,
44 | Height = border_size,
45 | Origin = Anchor.BottomCentre,
46 | Anchor = Anchor.BottomCentre,
47 | }
48 | };
49 | }
50 |
51 | [BackgroundDependencyLoader(true)]
52 | private void load([CanBeNull] DrawableHitObject drawableHitObject)
53 | {
54 | if (drawableHitObject != null)
55 | AccentColour.BindTo(drawableHitObject.AccentColour);
56 |
57 | AccentColour.BindValueChanged(c =>
58 | {
59 | backgroundBox.Colour = c.NewValue.Darken(1f);
60 | topBox.Colour = bottomBox.Colour = c.NewValue;
61 | triangles.Colour = c.NewValue;
62 | triangles.Alpha = 0.8f;
63 | }, true);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Drawables/Pieces/StarSheetCapStarPiece.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using JetBrains.Annotations;
5 | using osu.Framework.Allocation;
6 | using osu.Framework.Bindables;
7 | using osu.Framework.Extensions.Color4Extensions;
8 | using osu.Framework.Graphics;
9 | using osu.Framework.Graphics.Containers;
10 | using osu.Framework.Graphics.Shapes;
11 | using osu.Framework.Graphics.Sprites;
12 | using osu.Game.Graphics;
13 | using osu.Game.Graphics.Backgrounds;
14 | using osu.Game.Rulesets.Objects.Drawables;
15 | using osuTK;
16 | using osuTK.Graphics;
17 |
18 | namespace osu.Game.Rulesets.Rush.Objects.Drawables.Pieces
19 | {
20 | public partial class StarSheetCapStarPiece : CompositeDrawable, IHasAccentColour
21 | {
22 | private const double rotation_time = 1000;
23 |
24 | private readonly SpriteIcon starIcon;
25 | private readonly Triangles triangles;
26 | private readonly Box backgroundBox;
27 |
28 | public readonly Bindable AccentColour = new Bindable();
29 |
30 | Color4 IHasAccentColour.AccentColour
31 | {
32 | get => AccentColour.Value;
33 | set => AccentColour.Value = value;
34 | }
35 |
36 | public StarSheetCapStarPiece()
37 | {
38 | Origin = Anchor.Centre;
39 | Anchor = Anchor.Centre;
40 | Size = new Vector2(DrawableStarSheet.NOTE_SHEET_SIZE);
41 |
42 | AddRangeInternal(new Drawable[]
43 | {
44 | starIcon = new SpriteIcon
45 | {
46 | Anchor = Anchor.Centre,
47 | Scale = new Vector2(1.5f),
48 | RelativeSizeAxes = Axes.Both,
49 | Icon = FontAwesome.Solid.Star,
50 | },
51 | new CircularContainer
52 | {
53 | Anchor = Anchor.Centre,
54 | Origin = Anchor.Centre,
55 | RelativeSizeAxes = Axes.Both,
56 | BorderThickness = DrawableStarSheet.NOTE_SHEET_SIZE * 0.1f,
57 | BorderColour = Color4.White,
58 | Masking = true,
59 | Children = new Drawable[]
60 | {
61 | backgroundBox = new Box { RelativeSizeAxes = Axes.Both },
62 | triangles = new Triangles { RelativeSizeAxes = Axes.Both }
63 | }
64 | }
65 | });
66 | }
67 |
68 | [BackgroundDependencyLoader(true)]
69 | private void load([CanBeNull] DrawableHitObject drawableHitObject)
70 | {
71 | if (drawableHitObject != null)
72 | AccentColour.BindTo(drawableHitObject.AccentColour);
73 |
74 | AccentColour.BindValueChanged(c =>
75 | {
76 | starIcon.Colour = c.NewValue.Lighten(0.5f);
77 | backgroundBox.Colour = c.NewValue.Darken(0.5f);
78 | triangles.Colour = c.NewValue;
79 | triangles.Alpha = 0.8f;
80 | }, true);
81 | }
82 |
83 | protected override void Update()
84 | {
85 | base.Update();
86 |
87 | starIcon.OriginPosition = new Vector2(DrawWidth * 0.5f, DrawHeight * 0.54f);
88 | starIcon.Rotation = (float)(Time.Current % rotation_time / rotation_time) * 360f;
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/DualHit.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Threading;
5 | using osu.Game.Rulesets.Judgements;
6 | using osu.Game.Rulesets.Rush.Judgements;
7 | using osu.Game.Rulesets.Scoring;
8 |
9 | namespace osu.Game.Rulesets.Rush.Objects
10 | {
11 | public class DualHit : RushHitObject
12 | {
13 | public override double StartTime
14 | {
15 | get => base.StartTime;
16 | set
17 | {
18 | base.StartTime = value;
19 | Air.StartTime = Ground.StartTime = value;
20 | }
21 | }
22 |
23 | public readonly DualHitPart Air = new DualHitPart { Lane = LanedHitLane.Air };
24 | public readonly DualHitPart Ground = new DualHitPart { Lane = LanedHitLane.Ground };
25 |
26 | public override Judgement CreateJudgement() => new RushIgnoreJudgement();
27 |
28 | protected override HitWindows CreateHitWindows() => HitWindows.Empty;
29 |
30 | protected override bool HasFeverBonus => false;
31 |
32 | protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
33 | {
34 | base.CreateNestedHitObjects(cancellationToken);
35 |
36 | AddNested(Air);
37 | AddNested(Ground);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/DualHitPart.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Rush.Judgements;
6 |
7 | namespace osu.Game.Rulesets.Rush.Objects
8 | {
9 | public class DualHitPart : LanedHit
10 | {
11 | public override Judgement CreateJudgement() => new CollisionDamagingJudgement();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/FeverBonus.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Rush.Judgements;
6 | using osu.Game.Rulesets.Scoring;
7 |
8 | namespace osu.Game.Rulesets.Rush.Objects
9 | {
10 | public class FeverBonus : RushHitObject
11 | {
12 | public override Judgement CreateJudgement() => new RushFeverJudgement();
13 |
14 | protected override HitWindows CreateHitWindows() => HitWindows.Empty;
15 |
16 | protected override bool HasFeverBonus => false;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Heart.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Rush.Judgements;
6 | using osu.Game.Rulesets.Rush.Scoring;
7 | using osu.Game.Rulesets.Scoring;
8 |
9 | namespace osu.Game.Rulesets.Rush.Objects
10 | {
11 | public class Heart : LanedHit
12 | {
13 | public override Judgement CreateJudgement() => new HeartJudgement();
14 |
15 | protected override HitWindows CreateHitWindows() => new HeartHitWindows();
16 |
17 | protected override bool HasFeverBonus => false;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/LanedHit.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Bindables;
5 | using osu.Game.Rulesets.Judgements;
6 | using osu.Game.Rulesets.Rush.Judgements;
7 |
8 | namespace osu.Game.Rulesets.Rush.Objects
9 | {
10 | public class LanedHit : RushHitObject
11 | {
12 | public readonly Bindable LaneBindable = new Bindable();
13 |
14 | public virtual LanedHitLane Lane
15 | {
16 | get => LaneBindable.Value;
17 | set => LaneBindable.Value = value;
18 | }
19 |
20 | public override Judgement CreateJudgement() => new RushJudgement();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/LanedHitLane.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | namespace osu.Game.Rulesets.Rush.Objects
5 | {
6 | public enum LanedHitLane
7 | {
8 | ///
9 | /// Must press the air attack key.
10 | ///
11 | Air,
12 |
13 | ///
14 | /// Must press the ground attack key.
15 | ///
16 | Ground,
17 | }
18 |
19 | public static class LanedHitLaneExtensions
20 | {
21 | public static LanedHitLane Opposite(this LanedHitLane lane) => lane == LanedHitLane.Air ? LanedHitLane.Ground : LanedHitLane.Air;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/MiniBoss.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using System.Threading;
6 | using osu.Game.Rulesets.Judgements;
7 | using osu.Game.Rulesets.Objects.Types;
8 | using osu.Game.Rulesets.Rush.Judgements;
9 | using osu.Game.Rulesets.Scoring;
10 |
11 | namespace osu.Game.Rulesets.Rush.Objects
12 | {
13 | public class MiniBoss : RushHitObject, IHasDuration
14 | {
15 | public static readonly int DEFAULT_REQUIRED_HITS_PER_SECOND = 3;
16 |
17 | public double EndTime
18 | {
19 | get => StartTime + Duration;
20 | set => Duration = value - StartTime;
21 | }
22 |
23 | public double Duration { get; set; }
24 |
25 | public int RequiredHitsPerSecond => DEFAULT_REQUIRED_HITS_PER_SECOND;
26 |
27 | public int RequiredHits => (int)(Math.Ceiling(Duration / 500f) * RequiredHitsPerSecond * 0.5f);
28 |
29 | protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
30 | {
31 | base.CreateNestedHitObjects(cancellationToken);
32 |
33 | for (int i = 0; i < RequiredHits; i++)
34 | AddNested(new MiniBossTick());
35 | }
36 |
37 | public override Judgement CreateJudgement() => new RushJudgement();
38 |
39 | protected override HitWindows CreateHitWindows() => HitWindows.Empty;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/MiniBossTick.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Rush.Judgements;
6 | using osu.Game.Rulesets.Scoring;
7 |
8 | namespace osu.Game.Rulesets.Rush.Objects
9 | {
10 | public class MiniBossTick : RushHitObject
11 | {
12 | public override Judgement CreateJudgement() => new RushTickJudgement();
13 |
14 | protected override HitWindows CreateHitWindows() => HitWindows.Empty;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Minion.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Rush.Judgements;
6 |
7 | namespace osu.Game.Rulesets.Rush.Objects
8 | {
9 | ///
10 | /// Uses a sprite based on the beatmap environment and note hitsound.
11 | ///
12 | public class Minion : LanedHit
13 | {
14 | public override Judgement CreateJudgement() => new CollisionDamagingJudgement();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/RushHitObject.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Threading;
5 | using osu.Game.Rulesets.Judgements;
6 | using osu.Game.Rulesets.Objects;
7 | using osu.Game.Rulesets.Rush.Judgements;
8 | using osu.Game.Rulesets.Rush.Scoring;
9 | using osu.Game.Rulesets.Scoring;
10 |
11 | namespace osu.Game.Rulesets.Rush.Objects
12 | {
13 | public class RushHitObject : HitObject
14 | {
15 | public override Judgement CreateJudgement() => new RushJudgement();
16 |
17 | protected override HitWindows CreateHitWindows() => new RushHitWindows();
18 |
19 | protected virtual bool HasFeverBonus => true;
20 |
21 | protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
22 | {
23 | base.CreateNestedHitObjects(cancellationToken);
24 |
25 | if (HasFeverBonus)
26 | AddNested(new FeverBonus() { StartTime = this.GetEndTime() });
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/Sawblade.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Rush.Judgements;
6 | using osu.Game.Rulesets.Rush.Scoring;
7 | using osu.Game.Rulesets.Scoring;
8 |
9 | namespace osu.Game.Rulesets.Rush.Objects
10 | {
11 | public class Sawblade : LanedHit
12 | {
13 | public override Judgement CreateJudgement() => new SawbladeJudgement();
14 |
15 | protected override HitWindows CreateHitWindows() => new SawbladeHitWindows();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/StarSheet.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading;
7 | using osu.Game.Audio;
8 | using osu.Game.Rulesets.Judgements;
9 | using osu.Game.Rulesets.Objects.Types;
10 | using osu.Game.Rulesets.Rush.Judgements;
11 | using osu.Game.Rulesets.Scoring;
12 |
13 | namespace osu.Game.Rulesets.Rush.Objects
14 | {
15 | public class StarSheet : LanedHit, IHasDuration
16 | {
17 | public IList> NodeSamples;
18 |
19 | public double EndTime
20 | {
21 | get => StartTime + Duration;
22 | set => Duration = value - StartTime;
23 | }
24 |
25 | private double duration;
26 |
27 | public double Duration
28 | {
29 | get => duration;
30 | set
31 | {
32 | duration = value;
33 | Tail.StartTime = EndTime;
34 | }
35 | }
36 |
37 | public override double StartTime
38 | {
39 | get => base.StartTime;
40 | set
41 | {
42 | base.StartTime = value;
43 | Head.StartTime = value;
44 | Tail.StartTime = EndTime;
45 | }
46 | }
47 |
48 | public override LanedHitLane Lane
49 | {
50 | get => base.Lane;
51 | set
52 | {
53 | base.Lane = value;
54 | Head.Lane = value;
55 | Tail.Lane = value;
56 | }
57 | }
58 |
59 | public readonly StarSheetHead Head = new StarSheetHead();
60 |
61 | public readonly StarSheetTail Tail = new StarSheetTail();
62 |
63 | protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
64 | {
65 | base.CreateNestedHitObjects(cancellationToken);
66 |
67 | AddNested(Head);
68 | AddNested(Tail);
69 |
70 | updateNestedSamples();
71 | }
72 |
73 | private void updateNestedSamples()
74 | {
75 | if (NodeSamples.Count == 0)
76 | return;
77 |
78 | Head.Samples = NodeSamples.First();
79 | Tail.Samples = NodeSamples.Last();
80 | }
81 |
82 | public override Judgement CreateJudgement() => new RushIgnoreJudgement();
83 |
84 | protected override HitWindows CreateHitWindows() => HitWindows.Empty;
85 |
86 | protected override bool HasFeverBonus => false;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/StarSheetHead.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Rush.Judgements;
6 |
7 | namespace osu.Game.Rulesets.Rush.Objects
8 | {
9 | public class StarSheetHead : LanedHit
10 | {
11 | public override Judgement CreateJudgement() => new RushJudgement();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Objects/StarSheetTail.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Rush.Judgements;
6 |
7 | namespace osu.Game.Rulesets.Rush.Objects
8 | {
9 | public class StarSheetTail : LanedHit
10 | {
11 | public override Judgement CreateJudgement() => new RushJudgement();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Replays/RushFramedReplayInputHandler.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using osu.Framework.Input.StateChanges;
7 | using osu.Game.Replays;
8 | using osu.Game.Rulesets.Replays;
9 | using osu.Game.Rulesets.Rush.Configuration;
10 | using osu.Game.Rulesets.Rush.Input;
11 |
12 | namespace osu.Game.Rulesets.Rush.Replays
13 | {
14 | public class RushFramedReplayInputHandler : FramedReplayInputHandler
15 | {
16 | public RushFramedReplayInputHandler(Replay replay)
17 | : base(replay)
18 | {
19 | }
20 |
21 | protected override bool IsImportant(RushReplayFrame frame) => frame.Actions.Any();
22 |
23 | ///
24 | /// The current fever activation mode determined by the replay's current frame.
25 | ///
26 | public FeverActivationMode? FeverActivationMode => CurrentFrame?.FeverActivationMode;
27 |
28 | protected override void CollectReplayInputs(List inputs) =>
29 | inputs.Add(new ReplayState { PressedActions = CurrentFrame?.Actions ?? new List() });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Replays/RushReplayFrame.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using System.Diagnostics;
6 | using osu.Framework.Extensions.EnumExtensions;
7 | using osu.Game.Beatmaps;
8 | using osu.Game.Replays.Legacy;
9 | using osu.Game.Rulesets.Replays;
10 | using osu.Game.Rulesets.Replays.Types;
11 | using osu.Game.Rulesets.Rush.Configuration;
12 | using osu.Game.Rulesets.Rush.Input;
13 |
14 | namespace osu.Game.Rulesets.Rush.Replays
15 | {
16 | public class RushReplayFrame : ReplayFrame, IConvertibleReplayFrame
17 | {
18 | public List Actions = new List();
19 |
20 | ///
21 | /// The fever activation mode at this frame.
22 | ///
23 | public FeverActivationMode FeverActivationMode;
24 |
25 | public RushReplayFrame()
26 | {
27 | }
28 |
29 | public RushReplayFrame(double time, RushAction? button = null)
30 | : base(time)
31 | {
32 | if (button.HasValue)
33 | Actions.Add(button.Value);
34 | }
35 |
36 | public RushReplayFrame(double time, IEnumerable buttons)
37 | : base(time)
38 | {
39 | Actions.AddRange(buttons);
40 | }
41 |
42 | public void FromLegacy(LegacyReplayFrame currentFrame, IBeatmap beatmap, ReplayFrame lastFrame = null)
43 | {
44 | Debug.Assert(currentFrame.MouseX != null);
45 |
46 | uint flags = (uint)currentFrame.MouseX;
47 |
48 | int currentBit = 0;
49 |
50 | while (flags > 0)
51 | {
52 | if ((flags & 1) > 0)
53 | Actions.Add((RushAction)currentBit);
54 |
55 | ++currentBit;
56 | flags >>= 1;
57 | }
58 |
59 | // We are repurposing ReplayButtonState.Smoke in order to store the AutoFever setting used at the time of recording.
60 | // This will serve as an interim solution until non-legacy replays are supported in osu.
61 | FeverActivationMode = getFeverActivationMode(currentFrame.ButtonState);
62 | }
63 |
64 | public LegacyReplayFrame ToLegacy(IBeatmap beatmap)
65 | {
66 | uint flags = 0;
67 | foreach (var action in Actions)
68 | flags |= 1u << (int)action;
69 |
70 | return new LegacyReplayFrame(Time, flags, 0f, getFeverActivationButtonState(FeverActivationMode));
71 | }
72 |
73 | private static FeverActivationMode getFeverActivationMode(ReplayButtonState buttonState) => buttonState.HasFlag(ReplayButtonState.Smoke) switch
74 | {
75 | true => FeverActivationMode.Automatic,
76 | false => FeverActivationMode.Manual
77 | };
78 |
79 | private static ReplayButtonState getFeverActivationButtonState(FeverActivationMode mode) => mode switch
80 | {
81 | FeverActivationMode.Automatic => ReplayButtonState.Smoke,
82 | _ => ReplayButtonState.None,
83 | };
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Effects/explosion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Effects/explosion.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_0.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_1.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_hurt_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_hurt_0.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_hurt_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_hurt_1.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_hurt_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/MiniBoss/pippidon_boss_hurt_2.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_air_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_air_0.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_air_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_air_1.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_air_hit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_air_hit.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_ground_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_ground_0.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_ground_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_ground_1.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_ground_hit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Minion/pippidon_ground_hit.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__000.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__001.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__001.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__002.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__003.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__004.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__004.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__005.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__005.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__006.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__006.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__007.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__007.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__008.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__008.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__009.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Attack__009.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Dead__000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Dead__000.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__000.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__001.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__001.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__002.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__003.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__004.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__004.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__005.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__005.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__006.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__006.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__007.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__007.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__008.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__008.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__009.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump_Attack__009.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__000.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__001.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__001.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__002.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__003.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__004.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__004.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__005.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__005.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__006.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__006.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__007.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__007.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__008.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__008.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__009.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Jump__009.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__000.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__001.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__001.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__002.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__003.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__004.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__004.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__005.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__005.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__006.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__006.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__007.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__007.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__008.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__008.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__009.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Run__009.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__000.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__001.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__001.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__002.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__002.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__003.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__003.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__004.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__004.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__005.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__005.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__006.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__006.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__007.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__007.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__008.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__008.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__009.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Beamographic/rush/099eb77d51b7e491fd9259221472d351103ca4c8/osu.Game.Rulesets.Rush/Resources/Textures/Player/Slide__009.png
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/RushDifficultyCalculator.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using osu.Game.Beatmaps;
8 | using osu.Game.Rulesets.Difficulty;
9 | using osu.Game.Rulesets.Difficulty.Preprocessing;
10 | using osu.Game.Rulesets.Difficulty.Skills;
11 | using osu.Game.Rulesets.Mods;
12 |
13 | namespace osu.Game.Rulesets.Rush
14 | {
15 | public class RushDifficultyCalculator : DifficultyCalculator
16 | {
17 | public RushDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
18 | : base(ruleset, beatmap)
19 | {
20 | }
21 |
22 | protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
23 | {
24 | return new DifficultyAttributes(mods, 0) { StarRating = beatmap.BeatmapInfo.StarRating };
25 | }
26 |
27 | protected override IEnumerable CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty();
28 |
29 | protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => Array.Empty();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/RushSkinComponent.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Skinning;
5 |
6 | namespace osu.Game.Rulesets.Rush
7 | {
8 | public class RushSkinComponent : SkinComponentLookup
9 | {
10 | public RushSkinComponent(RushSkinComponents component)
11 | : base(component)
12 | {
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/RushSkinComponents.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | namespace osu.Game.Rulesets.Rush
5 | {
6 | public enum RushSkinComponents
7 | {
8 | Minion,
9 | StarSheetHead,
10 | StarSheetTail,
11 | StarSheetBody,
12 | StarSheetHold,
13 | StarSheetExplosion,
14 | Miniboss,
15 | Sawblade,
16 | DualHitPart,
17 | DualHitJoin,
18 | Heart,
19 | AirHitTarget,
20 | GroundHitTarget,
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Scoring/HeartHitWindows.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Scoring;
5 |
6 | namespace osu.Game.Rulesets.Rush.Scoring
7 | {
8 | public class HeartHitWindows : RushHitWindows
9 | {
10 | protected override DifficultyRange[] GetRanges() => new[]
11 | {
12 | new DifficultyRange(HitResult.Great, 50, 50, 50),
13 | new DifficultyRange(HitResult.Miss, 200, 200, 200)
14 | };
15 |
16 | public override bool IsHitResultAllowed(HitResult result) => result == HitResult.Great || result == HitResult.Miss;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Scoring/RushHealthProcessor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Objects;
6 | using osu.Game.Rulesets.Rush.Judgements;
7 | using osu.Game.Rulesets.Rush.Objects;
8 | using osu.Game.Rulesets.Scoring;
9 |
10 | namespace osu.Game.Rulesets.Rush.Scoring
11 | {
12 | public partial class RushHealthProcessor : HealthProcessor
13 | {
14 | public double PlayerHealthPercentage { get; }
15 |
16 | public RushHealthProcessor(double playerHealthPercentage = 100f)
17 | {
18 | PlayerHealthPercentage = playerHealthPercentage;
19 | }
20 |
21 | protected virtual double GetHealthPointIncreaseFor(RushJudgementResult result) => result.Judgement.HealthPointIncreaseFor(result);
22 |
23 | protected sealed override double GetHealthIncreaseFor(JudgementResult result)
24 | {
25 | var pointIncrease = GetHealthPointIncreaseFor((RushJudgementResult)result);
26 | return pointIncrease / PlayerHealthPercentage;
27 | }
28 |
29 | protected override JudgementResult CreateResult(HitObject hitObject, Judgement judgement) => new RushJudgementResult((RushHitObject)hitObject, (RushJudgement)judgement);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Scoring/RushHitWindows.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Scoring;
5 |
6 | namespace osu.Game.Rulesets.Rush.Scoring
7 | {
8 | public class RushHitWindows : HitWindows
9 | {
10 | protected override DifficultyRange[] GetRanges() => new[]
11 | {
12 | new DifficultyRange(HitResult.Great, 80, 50, 20),
13 | new DifficultyRange(HitResult.Good, 160, 120, 80),
14 | new DifficultyRange(HitResult.Miss, 200, 180, 160),
15 | };
16 |
17 | public override bool IsHitResultAllowed(HitResult result) =>
18 | result switch
19 | {
20 | HitResult.Miss => true,
21 | HitResult.Good => true,
22 | HitResult.Great => true,
23 | _ => false
24 | };
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Scoring/RushScoreProcessor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Judgements;
5 | using osu.Game.Rulesets.Objects;
6 | using osu.Game.Rulesets.Rush.Judgements;
7 | using osu.Game.Rulesets.Rush.Objects;
8 | using osu.Game.Rulesets.Scoring;
9 |
10 | namespace osu.Game.Rulesets.Rush.Scoring
11 | {
12 | public partial class RushScoreProcessor : ScoreProcessor
13 | {
14 | public RushScoreProcessor(RushRuleset ruleset) : base(ruleset) { }
15 |
16 | protected override JudgementResult CreateResult(HitObject hitObject, Judgement judgement) =>
17 | new RushJudgementResult((RushHitObject)hitObject, (RushJudgement)judgement);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/Scoring/SawbladeHitWindows.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Game.Rulesets.Scoring;
5 |
6 | namespace osu.Game.Rulesets.Rush.Scoring
7 | {
8 | public class SawbladeHitWindows : RushHitWindows
9 | {
10 | protected override DifficultyRange[] GetRanges() => new[]
11 | {
12 | new DifficultyRange(HitResult.Great, 20, 20, 20),
13 | new DifficultyRange(HitResult.Miss, 50, 50, 50)
14 | };
15 |
16 | public override bool IsHitResultAllowed(HitResult result) => result == HitResult.Great || result == HitResult.Miss;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/ActionBeatSyncedContainer.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using osu.Framework.Audio.Track;
6 | using osu.Game.Beatmaps.ControlPoints;
7 | using osu.Game.Graphics.Containers;
8 |
9 | namespace osu.Game.Rulesets.Rush.UI
10 | {
11 | public partial class ActionBeatSyncedContainer : BeatSyncedContainer
12 | {
13 | public Action NewBeat;
14 |
15 | protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) =>
16 | NewBeat?.Invoke(beatIndex, timingPoint, effectPoint, amplitudes);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/DefaultHitExplosion.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using System.Linq;
6 | using osu.Framework.Allocation;
7 | using osu.Framework.Extensions.Color4Extensions;
8 | using osu.Framework.Graphics;
9 | using osu.Framework.Graphics.Containers;
10 | using osu.Framework.Graphics.Pooling;
11 | using osu.Framework.Graphics.Shapes;
12 | using osu.Framework.Graphics.Sprites;
13 | using osu.Framework.Graphics.Textures;
14 | using osu.Framework.Utils;
15 | using osu.Game.Rulesets.Objects.Drawables;
16 | using osu.Game.Rulesets.Rush.Objects.Drawables;
17 | using osuTK;
18 | using osuTK.Graphics;
19 |
20 | namespace osu.Game.Rulesets.Rush.UI
21 | {
22 | public partial class DefaultHitExplosion : PoolableDrawable
23 | {
24 | private readonly Sprite colouredExplosion;
25 | private readonly Sprite whiteExplosion;
26 |
27 | private readonly Sparks sparks;
28 |
29 | public override bool RemoveWhenNotAlive => true;
30 | public override bool RemoveCompletedTransforms => false;
31 |
32 | public DefaultHitExplosion()
33 | : this(Color4.White)
34 | {
35 | }
36 |
37 | public DefaultHitExplosion(Color4 explosionColour, int sparkCount = 10, Color4? sparkColour = null)
38 | {
39 | Depth = 1f;
40 | Origin = Anchor.Centre;
41 | Size = new Vector2(200, 200);
42 | Scale = new Vector2(0.9f + RNG.NextSingle() * 0.2f);
43 |
44 | InternalChildren = new Drawable[]
45 | {
46 | colouredExplosion = new Sprite
47 | {
48 | Anchor = Anchor.Centre,
49 | Origin = Anchor.Centre,
50 | Colour = explosionColour,
51 | Scale = new Vector2(1f)
52 | },
53 | whiteExplosion = new Sprite
54 | {
55 | Anchor = Anchor.Centre,
56 | Origin = Anchor.Centre,
57 | Scale = new Vector2(0.75f)
58 | },
59 | sparks = new Sparks(sparkCount)
60 | {
61 | Anchor = Anchor.Centre,
62 | Origin = Anchor.Centre,
63 | RelativeSizeAxes = Axes.Both,
64 | Size = new Vector2(2f),
65 | Colour = sparkColour ?? Color4.White
66 | }
67 | // TODO: stars
68 | };
69 | }
70 |
71 | public void Apply(DrawableHitObject hitObject)
72 | {
73 | if (hitObject is DrawableMiniBoss miniBoss)
74 | {
75 | Alpha = 0;
76 | Depth = 0;
77 | Origin = Anchor.Centre;
78 | Anchor = miniBoss.Anchor;
79 | Size = new Vector2(200, 200);
80 | Scale = new Vector2(0.9f + RNG.NextSingle() * 0.2f) * 1.5f;
81 | Rotation = RNG.NextSingle() * 360f;
82 | colouredExplosion.Colour = Color4.Yellow.Darken(0.5f);
83 | }
84 | else if (hitObject is IDrawableLanedHit laned)
85 | {
86 | colouredExplosion.Colour = laned.LaneAccentColour;
87 | Anchor = laned.LaneAnchor;
88 | Rotation = RNG.NextSingle() * 360f;
89 | }
90 | }
91 |
92 | [BackgroundDependencyLoader]
93 | private void load(TextureStore store)
94 | {
95 | colouredExplosion.Texture = store.Get("Effects/explosion");
96 | whiteExplosion.Texture = store.Get("Effects/explosion");
97 | }
98 |
99 | protected override void PrepareForUse()
100 | {
101 | ApplyTransformsAt(double.MinValue, true);
102 | ClearTransforms(true);
103 | ApplyExplosionTransforms();
104 | }
105 |
106 | ///
107 | /// Applies all transforms to animate the explosion.
108 | ///
109 | protected virtual void ApplyExplosionTransforms()
110 | {
111 | this.ScaleTo(Scale * 0.5f, RushPlayfield.HIT_EXPLOSION_DURATION)
112 | .FadeOutFromOne(RushPlayfield.HIT_EXPLOSION_DURATION)
113 | .Expire(true);
114 |
115 | sparks.Animate();
116 | }
117 |
118 | protected partial class Sparks : CompositeDrawable
119 | {
120 | public override bool RemoveCompletedTransforms => false;
121 |
122 | private const double average_duration = 1500f;
123 |
124 | private readonly Random random = new Random();
125 | private readonly Triangle[] triangles;
126 |
127 | private double randomDirection(int index, int max)
128 | {
129 | var offset = random.NextDouble() * 2f / max;
130 | return (double)index / max + offset;
131 | }
132 |
133 | public Sparks(int sparkCount)
134 | {
135 | Origin = Anchor.Centre;
136 | Anchor = Anchor.Centre;
137 | RelativeSizeAxes = Axes.Both;
138 |
139 | triangles = Enumerable.Range(0, sparkCount).Select(i => new Triangle
140 | {
141 | Origin = Anchor.Centre,
142 | Anchor = Anchor.Centre,
143 | Size = new Vector2(5f, 10f),
144 | Rotation = (float)(randomDirection(i, sparkCount) * 360),
145 | }).ToArray();
146 |
147 | InternalChildren = triangles;
148 | }
149 |
150 | public void Animate()
151 | {
152 | foreach (var triangle in triangles)
153 | {
154 | var scale = 0.8f + random.NextDouble() * 0.2f;
155 | var duration = average_duration * (0.8f + random.NextDouble() * 0.4f);
156 | var radians = float.DegreesToRadians(triangle.Rotation + 90);
157 | var distance = DrawWidth * (0.8f + random.NextDouble() * 0.2f);
158 | var target = new Vector2(MathF.Cos(radians), MathF.Sin(radians)) * (float)distance;
159 | triangle.Scale = new Vector2((float)scale);
160 | triangle.MoveTo(target, duration, Easing.OutExpo);
161 | triangle.FadeOutFromOne(duration, Easing.InExpo);
162 | }
163 | }
164 | }
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/DrawableRushRuleset.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using osu.Framework.Allocation;
6 | using osu.Framework.Bindables;
7 | using osu.Framework.Input;
8 | using osu.Game.Beatmaps;
9 | using osu.Game.Configuration;
10 | using osu.Game.Input.Handlers;
11 | using osu.Game.Replays;
12 | using osu.Game.Rulesets.Mods;
13 | using osu.Game.Rulesets.Objects;
14 | using osu.Game.Rulesets.Objects.Drawables;
15 | using osu.Game.Rulesets.Rush.Configuration;
16 | using osu.Game.Rulesets.Rush.Input;
17 | using osu.Game.Rulesets.Rush.Objects;
18 | using osu.Game.Rulesets.Rush.Replays;
19 | using osu.Game.Rulesets.Rush.UI.Fever;
20 | using osu.Game.Rulesets.UI;
21 | using osu.Game.Rulesets.UI.Scrolling;
22 | using osu.Game.Scoring;
23 |
24 | namespace osu.Game.Rulesets.Rush.UI
25 | {
26 | [Cached]
27 | public partial class DrawableRushRuleset : DrawableScrollingRuleset
28 | {
29 | private FeverProcessor feverProcessor;
30 |
31 | protected new RushRulesetConfigManager Config => (RushRulesetConfigManager)base.Config;
32 |
33 | public new RushPlayfield Playfield => (RushPlayfield)base.Playfield;
34 |
35 | public new RushInputManager KeyBindingInputManager => (RushInputManager)base.KeyBindingInputManager;
36 |
37 | public FeverActivationMode FeverActivationMode => KeyBindingInputManager.ReplayInputHandler?.FeverActivationMode ?? feverActivationModeSetting.Value;
38 |
39 | protected override bool UserScrollSpeedAdjustment => true;
40 |
41 | public DrawableRushRuleset(RushRuleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null)
42 | : base(ruleset, beatmap, mods)
43 | {
44 | Direction.Value = ScrollingDirection.Left;
45 | TimeRange.Value = 800;
46 | VisualisationMethod = ScrollVisualisationMethod.Constant;
47 | }
48 |
49 | protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
50 | {
51 | var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
52 |
53 | dependencies.CacheAs(feverProcessor = new FeverProcessor());
54 |
55 | NewResult += feverProcessor.ApplyResult;
56 | RevertResult += feverProcessor.RevertResult;
57 |
58 | return dependencies;
59 | }
60 |
61 | private readonly Bindable feverActivationModeSetting = new Bindable();
62 |
63 | [BackgroundDependencyLoader]
64 | private void load()
65 | {
66 | Config?.BindWith(RushRulesetSettings.FeverActivationMode, feverActivationModeSetting);
67 |
68 | FrameStableComponents.Add(feverProcessor);
69 | }
70 |
71 | public bool PlayerCollidesWith(HitObject hitObject) => Playfield.PlayerSprite.CollidesWith(hitObject);
72 |
73 | protected override Playfield CreatePlayfield() => new RushPlayfield();
74 |
75 | protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new RushFramedReplayInputHandler(replay);
76 |
77 | protected override ReplayRecorder CreateReplayRecorder(Score score) => new RushReplayRecorder(score);
78 |
79 | public override DrawableHitObject CreateDrawableRepresentation(RushHitObject h) => null;
80 |
81 | protected override PassThroughInputManager CreateInputManager() => new RushInputManager(Ruleset?.RulesetInfo);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/Fever/RushFeverBar.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System;
5 | using osu.Framework.Allocation;
6 | using osu.Framework.Bindables;
7 | using osu.Framework.Extensions.Color4Extensions;
8 | using osu.Framework.Graphics;
9 | using osu.Framework.Graphics.Containers;
10 | using osu.Framework.Graphics.Effects;
11 | using osu.Framework.Graphics.Shapes;
12 | using osu.Framework.Localisation;
13 | using osu.Game.Graphics;
14 | using osu.Game.Graphics.Sprites;
15 | using osu.Game.Graphics.UserInterface;
16 | using osu.Game.Rulesets.Rush.Input;
17 | using osuTK;
18 | using osuTK.Graphics;
19 |
20 | namespace osu.Game.Rulesets.Rush.UI.Fever
21 | {
22 | public partial class FeverBar : CircularContainer, IKeyBindingTouchHandler
23 | {
24 | public override bool HandlePositionalInput => true;
25 |
26 | private Box progressBar;
27 |
28 | public override bool RemoveCompletedTransforms => true;
29 |
30 | public FeverBar()
31 | {
32 | Y = 150;
33 | Anchor = Anchor.BottomCentre;
34 | Origin = Anchor.TopCentre;
35 | RelativeSizeAxes = Axes.X;
36 | Size = new Vector2(0.5f, 50);
37 | Masking = true;
38 | BorderColour = Color4.Violet;
39 | BorderThickness = 5;
40 | EdgeEffect = new EdgeEffectParameters
41 | {
42 | Colour = Color4.DeepPink.Opacity(0),
43 | Type = EdgeEffectType.Glow,
44 | Radius = 20,
45 | };
46 | }
47 |
48 | private IBindable inFeverMode;
49 | private IBindable feverProgress;
50 |
51 | [BackgroundDependencyLoader]
52 | private void load(FeverProcessor processor)
53 | {
54 | feverProgress = processor.FeverProgress.GetBoundCopy();
55 | inFeverMode = processor.InFeverMode.GetBoundCopy();
56 |
57 | Children = new Drawable[]
58 | {
59 | new Box
60 | {
61 | RelativeSizeAxes = Axes.Both,
62 | Colour = Color4.Purple,
63 | },
64 | progressBar = new Box
65 | {
66 | RelativeSizeAxes = Axes.Both,
67 | Colour = Color4.DeepPink,
68 | Size = new Vector2(0, 1),
69 | },
70 | new Container
71 | {
72 | RelativeSizeAxes = Axes.Both,
73 | Padding = new MarginPadding(15),
74 | Children = new Drawable[]
75 | {
76 | new OsuSpriteText
77 | {
78 | Anchor = Anchor.CentreLeft,
79 | Origin = Anchor.CentreLeft,
80 | Text = "FEVER",
81 | Colour = Color4.White,
82 | Font = OsuFont.Numeric.With(size: 20),
83 | UseFullGlyphHeight = false
84 | },
85 | new FeverRollingCounter
86 | {
87 | Anchor = Anchor.CentreRight,
88 | Origin = Anchor.CentreRight,
89 | Colour = Color4.White,
90 | Current = { BindTarget = feverProgress }
91 | }
92 | }
93 | }
94 | };
95 |
96 | feverProgress.ValueChanged += updateProgressBar;
97 | inFeverMode.ValueChanged += updateFeverState;
98 | }
99 |
100 | private void updateProgressBar(ValueChangedEvent valueChanged)
101 | {
102 | if (!inFeverMode.Value)
103 | {
104 | if (valueChanged.NewValue >= 1 && valueChanged.OldValue < 1)
105 | FadeEdgeEffectTo(0.5f, 100);
106 | else if (valueChanged.NewValue < 1 && valueChanged.OldValue >= 1)
107 | FadeEdgeEffectTo(0f); // Just to support rewinds
108 | }
109 |
110 | progressBar.ResizeWidthTo(Math.Min(1, valueChanged.NewValue), 100);
111 |
112 | if (Clock.Rate < 0)
113 | FinishTransforms(true); // Force the animations to finish immediately when rewinding
114 | }
115 |
116 | private void updateFeverState(ValueChangedEvent valueChanged)
117 | {
118 | if (valueChanged.NewValue)
119 | {
120 | FadeEdgeEffectTo(Color4.Red, 100);
121 | progressBar.FadeColour(Color4.Red, 100);
122 | }
123 | else
124 | {
125 | FadeEdgeEffectTo(Color4.DeepPink.Opacity(0), 200);
126 | progressBar.FadeColour(Color4.DeepPink, 200);
127 | }
128 |
129 | if (Clock.Rate < 0)
130 | FinishTransforms(true); // Force the animations to finish immediately when rewinding
131 | }
132 |
133 | private RushInputManager rushActionInputManager;
134 | internal RushInputManager RushActionInputManager => rushActionInputManager ??= GetContainingInputManager() as RushInputManager;
135 |
136 | public RushActionTarget ActionTargetForTouchPosition(Vector2 screenSpaceTouchPos) => RushActionTarget.Fever;
137 |
138 | private partial class FeverRollingCounter : RollingCounter
139 | {
140 | protected override double RollingDuration => 100;
141 |
142 | public FeverRollingCounter()
143 | {
144 | Anchor = Anchor.Centre;
145 | Origin = Anchor.Centre;
146 | }
147 |
148 | protected override OsuSpriteText CreateSpriteText()
149 | {
150 | return new OsuSpriteText
151 | {
152 | Anchor = Anchor.Centre,
153 | Origin = Anchor.Centre,
154 | Font = OsuFont.Numeric.With(size: 20),
155 | UseFullGlyphHeight = false,
156 | };
157 | }
158 |
159 | protected override LocalisableString FormatCount(float count) => Math.Floor(Math.Min(count, 1) * 100).ToString("0\\%");
160 | }
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/Ground/DefaultGround.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Allocation;
5 | using osu.Framework.Extensions.Color4Extensions;
6 | using osu.Framework.Extensions.EnumExtensions;
7 | using osu.Framework.Graphics;
8 | using osu.Framework.Graphics.Colour;
9 | using osu.Framework.Graphics.Containers;
10 | using osu.Framework.Graphics.Pooling;
11 | using osu.Framework.Graphics.Shapes;
12 | using osu.Framework.Layout;
13 | using osu.Game.Rulesets.UI.Scrolling;
14 | using osuTK;
15 | using osuTK.Graphics;
16 |
17 | namespace osu.Game.Rulesets.Rush.UI.Ground
18 | {
19 | public partial class DefaultGround : CompositeDrawable
20 | {
21 | private static readonly Color4 platform_colour = Color4.Gray.Opacity(0.2f);
22 |
23 | private static readonly ColourInfo slat_colour = ColourInfo.GradientVertical(Color4.Gray.Opacity(0.8f), Color4.Gray.Opacity(0.4f));
24 | private static readonly Vector2 slat_size = new Vector2(10f, 100f);
25 |
26 | private const float slat_angle = -40f;
27 |
28 | private const float slats_spacing = 100f;
29 |
30 | private static readonly Color4 ground_colour = Color4.Gray.Opacity(0.2f);
31 |
32 | private readonly Container slats;
33 |
34 | private readonly DrawablePool linePool;
35 |
36 | public DefaultGround()
37 | {
38 | RelativeSizeAxes = Axes.Both;
39 |
40 | InternalChild = new FillFlowContainer
41 | {
42 | RelativeSizeAxes = Axes.Both,
43 | Direction = FillDirection.Vertical,
44 | Children = new Drawable[]
45 | {
46 | linePool = new DrawablePool(10),
47 | new Box
48 | {
49 | Name = "Top line",
50 | Colour = platform_colour.Opacity(1f).Lighten(1f),
51 | RelativeSizeAxes = Axes.X,
52 | Height = 3f,
53 | Depth = -1,
54 | },
55 | new Container
56 | {
57 | Name = "Platform",
58 | Masking = true,
59 | AutoSizeAxes = Axes.Y,
60 | RelativeSizeAxes = Axes.X,
61 | Children = new Drawable[]
62 | {
63 | new Box
64 | {
65 | RelativeSizeAxes = Axes.Both,
66 | Colour = platform_colour,
67 | },
68 | slats = new Container
69 | {
70 | AutoSizeAxes = Axes.Both,
71 | },
72 | }
73 | },
74 | new Box
75 | {
76 | Name = "Bottom line",
77 | Colour = platform_colour.Opacity(1f).Lighten(2f),
78 | RelativeSizeAxes = Axes.X,
79 | Height = 3f,
80 | },
81 | new Box
82 | {
83 | Name = "Ground",
84 | Colour = ground_colour,
85 | RelativeSizeAxes = Axes.Both,
86 | }
87 | }
88 | };
89 | }
90 |
91 | [Resolved(canBeNull: true)]
92 | private IScrollingInfo scrollingInfo { get; set; }
93 |
94 | protected override void UpdateAfterChildren()
95 | {
96 | base.UpdateAfterChildren();
97 |
98 | // Tests don't have scrolling info yet
99 | if (scrollingInfo is null) return;
100 |
101 | var groundX = scrollingInfo.Algorithm.Value.PositionAt(0f, Time.Current, scrollingInfo.TimeRange.Value, DrawWidth - RushPlayfield.HIT_TARGET_OFFSET) % slats_spacing;
102 |
103 | // This is to ensure that the ground is still visible before the start of the track
104 | if (groundX > 0)
105 | groundX = -slats_spacing + groundX;
106 |
107 | slats.X = groundX;
108 | }
109 |
110 | protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source)
111 | {
112 | if (invalidation.HasFlag(Invalidation.DrawSize))
113 | {
114 | slats.Clear(false);
115 |
116 | for (float i = 0; i < DrawWidth + slats_spacing; i += slats_spacing)
117 | slats.Add(linePool.Get(l => l.X = i));
118 | }
119 |
120 | return base.OnInvalidate(invalidation, source);
121 | }
122 |
123 | private partial class GroundLine : PoolableDrawable
124 | {
125 | public override bool RemoveWhenNotAlive => false;
126 |
127 | public GroundLine()
128 | {
129 | Colour = slat_colour;
130 | Anchor = Anchor.TopLeft;
131 | Origin = Anchor.TopLeft;
132 | Size = slat_size;
133 | Rotation = slat_angle;
134 | Margin = new MarginPadding { Bottom = -10f };
135 | InternalChild = new Box
136 | {
137 | RelativeSizeAxes = Axes.Both
138 | };
139 | }
140 | }
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/Ground/GroundDisplay.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Framework.Graphics.Containers;
6 |
7 | namespace osu.Game.Rulesets.Rush.UI.Ground
8 | {
9 | ///
10 | /// Represents a component displaying the ground the player will be standing on.
11 | ///
12 | public partial class GroundDisplay : CompositeDrawable
13 | {
14 | public GroundDisplay()
15 | {
16 | Anchor = Anchor.BottomCentre;
17 | Origin = Anchor.TopCentre;
18 | RelativeSizeAxes = Axes.Both;
19 | Padding = new MarginPadding { Top = 50f };
20 |
21 | InternalChildren = new Drawable[]
22 | {
23 | new DefaultGround(),
24 | };
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/HealthText.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Framework.Graphics.Pooling;
6 | using osu.Framework.Graphics.Sprites;
7 | using osuTK;
8 | using osuTK.Graphics;
9 |
10 | namespace osu.Game.Rulesets.Rush.UI
11 | {
12 | public partial class HealthText : PoolableDrawable
13 | {
14 | private readonly SpriteText text;
15 |
16 | public override bool RemoveCompletedTransforms => false;
17 |
18 | public HealthText()
19 | {
20 | Origin = Anchor.Centre;
21 | Anchor = Anchor.CentreLeft;
22 |
23 | InternalChildren = new Drawable[]
24 | {
25 | text = new SpriteText
26 | {
27 | Font = FontUsage.Default.With(size: 40),
28 | Scale = new Vector2(1.2f),
29 | }
30 | };
31 | }
32 |
33 | public void Apply(double pointDifference)
34 | {
35 | text.Colour = pointDifference > 0 ? Color4.Green : Color4.Red;
36 | text.Text = $"{pointDifference:+0;-0}";
37 | }
38 |
39 | protected override void PrepareForUse()
40 | {
41 | base.PrepareForUse();
42 |
43 | const float judgement_time = 250f;
44 |
45 | ApplyTransformsAt(double.MinValue);
46 | ClearTransforms();
47 |
48 | this.ScaleTo(1f, judgement_time)
49 | .Then()
50 | .FadeOutFromOne(judgement_time)
51 | .MoveToOffset(new Vector2(0f, -20f), judgement_time)
52 | .Expire(true);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/HeartHitExplosion.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Graphics;
5 | using osu.Game.Rulesets.Rush.Objects.Drawables;
6 | using osu.Game.Rulesets.Rush.Objects.Drawables.Pieces;
7 | using osuTK;
8 |
9 | namespace osu.Game.Rulesets.Rush.UI
10 | {
11 | public partial class HeartHitExplosion : HeartPiece
12 | {
13 | public override bool RemoveCompletedTransforms => false;
14 |
15 | public HeartHitExplosion()
16 | {
17 | Origin = Anchor.Centre;
18 | Scale = new Vector2(0.5f);
19 | }
20 |
21 | protected override void PrepareForUse()
22 | {
23 | ApplyTransformsAt(double.MinValue);
24 | ClearTransforms();
25 |
26 | this.ScaleTo(1.25f, RushPlayfield.HIT_EXPLOSION_DURATION)
27 | .FadeOutFromOne(RushPlayfield.HIT_EXPLOSION_DURATION)
28 | .Expire(true);
29 | }
30 |
31 | public void Apply(DrawableHeart drawableHeart)
32 | {
33 | Anchor = drawableHeart.LaneAnchor;
34 | Size = drawableHeart.Size;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/HitTarget.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Audio.Track;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Graphics.Containers;
7 | using osu.Framework.Graphics.Shapes;
8 | using osu.Game.Beatmaps.ControlPoints;
9 | using osu.Game.Graphics.Containers;
10 | using osuTK.Graphics;
11 |
12 | namespace osu.Game.Rulesets.Rush.UI
13 | {
14 | public partial class HitTarget : BeatSyncedContainer
15 | {
16 | public HitTarget()
17 | {
18 | Anchor = Anchor.Centre;
19 | Origin = Anchor.Centre;
20 | Children = new Drawable[]
21 | {
22 | new CircularContainer
23 | {
24 | Anchor = Anchor.Centre,
25 | Origin = Anchor.Centre,
26 | RelativeSizeAxes = Axes.Both,
27 | Masking = true,
28 | BorderColour = Color4.White,
29 | BorderThickness = 3f,
30 | Alpha = 0.35f,
31 | Child = new Box
32 | {
33 | RelativeSizeAxes = Axes.Both,
34 | Alpha = 0,
35 | AlwaysPresent = true
36 | }
37 | },
38 | };
39 | }
40 |
41 | protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) =>
42 | this.ScaleTo(1.2f)
43 | .Then()
44 | .ScaleTo(1f, timingPoint.BeatLength, Easing.Out);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/LanePlayfield.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Allocation;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Graphics.Containers;
7 | using osu.Framework.Graphics.Pooling;
8 | using osu.Game.Rulesets.Judgements;
9 | using osu.Game.Rulesets.Objects.Drawables;
10 | using osu.Game.Rulesets.Rush.Objects;
11 | using osu.Game.Rulesets.Rush.Objects.Drawables;
12 | using osu.Game.Rulesets.UI;
13 | using osu.Game.Rulesets.UI.Scrolling;
14 | using osuTK;
15 |
16 | namespace osu.Game.Rulesets.Rush.UI
17 | {
18 | public partial class LanePlayfield : ScrollingPlayfield
19 | {
20 | private readonly JudgementContainer judgementContainer;
21 | private readonly Container effectsContainer;
22 |
23 | private readonly LanedHitLane lane;
24 |
25 | public LanePlayfield(LanedHitLane type)
26 | {
27 | bool isAirLane = type == LanedHitLane.Air;
28 | lane = type;
29 |
30 | Name = $"{(isAirLane ? "Air" : "Ground")} Playfield";
31 | Padding = new MarginPadding { Left = RushPlayfield.HIT_TARGET_OFFSET };
32 | Anchor = Origin = isAirLane ? Anchor.TopCentre : Anchor.BottomCentre;
33 | RelativeSizeAxes = Axes.Both;
34 | Size = new Vector2(1, 0);
35 |
36 | AddRangeInternal(new Drawable[]
37 | {
38 | new Container
39 | {
40 | Name = "Hit Target",
41 | Anchor = Anchor.CentreLeft,
42 | Origin = Anchor.Centre,
43 | Size = new Vector2(RushPlayfield.HIT_TARGET_SIZE),
44 | Child = new HitTarget
45 | {
46 | RelativeSizeAxes = Axes.Both,
47 | },
48 | },
49 | effectsContainer = new Container(),
50 | judgementContainer = new JudgementContainer(),
51 | HitObjectContainer,
52 | });
53 | }
54 |
55 | [Resolved]
56 | private RushHitPolicy hitPolicy { get; set; }
57 |
58 | [BackgroundDependencyLoader]
59 | private void load()
60 | {
61 | registerLanedPool(4);
62 | registerLanedPool(2);
63 | registerLanedPool(8);
64 | registerLanedPool(8);
65 | registerLanedPool(8);
66 | registerLanedPool(8);
67 | RegisterPool(8);
68 | }
69 |
70 | protected override void OnNewDrawableHitObject(DrawableHitObject drawableHitObject)
71 | {
72 | base.OnNewDrawableHitObject(drawableHitObject);
73 |
74 | if (drawableHitObject is DrawableRushHitObject drho)
75 | drho.CheckHittable = hitPolicy.IsHittable;
76 | }
77 |
78 | private void registerLanedPool(int initialSize, int? maximumSize = null) where TObject : LanedHit where TDrawable : DrawableLanedHit, new()
79 | {
80 | RegisterPool(new DrawableLanedObjectPool(lane, initialSize, maximumSize));
81 | }
82 |
83 | public void AddExplosion(Drawable drawable) => effectsContainer.Add(drawable);
84 | public void AddJudgement(DrawableRushJudgement judgement) => judgementContainer.Add(judgement);
85 |
86 | // This pool pre-initializes created DrawableLanedObjects with a predefined lane value
87 | // The lane value needs to be set beforehand so that the pieces (Minion, etc) can load using the correct information
88 | private partial class DrawableLanedObjectPool : DrawablePool where T : PoolableDrawable, IDrawableLanedHit, new()
89 | {
90 | private readonly LanedHitLane lane;
91 |
92 | public DrawableLanedObjectPool(LanedHitLane lane, int initialSize, int? maximumSize)
93 | : base(initialSize, maximumSize)
94 | {
95 | this.lane = lane;
96 | }
97 |
98 | protected override T CreateNewDrawable() => new T() { Lane = lane };
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/RushHitPolicy.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using osu.Game.Rulesets.Objects;
7 | using osu.Game.Rulesets.Objects.Drawables;
8 | using osu.Game.Rulesets.Rush.Objects;
9 | using osu.Game.Rulesets.Rush.Objects.Drawables;
10 |
11 | namespace osu.Game.Rulesets.Rush.UI
12 | {
13 | public class RushHitPolicy
14 | {
15 | private readonly RushPlayfield playfield;
16 |
17 | private IEnumerable aliveHitObjects => playfield.AllAliveHitObjects;
18 |
19 | public RushHitPolicy(RushPlayfield playfield)
20 | {
21 | this.playfield = playfield;
22 | }
23 |
24 | public bool IsHittable(DrawableHitObject hitObject) => enumerateHitObjectsUpTo(hitObject.HitObject).All(obj => obj.AllJudged);
25 |
26 | private IEnumerable enumerateHitObjectsUpTo(HitObject hitobject)
27 | {
28 | double targetTime = hitobject.StartTime;
29 |
30 | foreach (var obj in aliveHitObjects)
31 | {
32 | if (obj.HitObject.StartTime >= targetTime)
33 | yield break;
34 |
35 | var laned = hitobject as LanedHit;
36 |
37 | if (laned != null)
38 | {
39 | // We don't want objects from another lane to block inputs
40 | if (obj is IDrawableLanedHit lanedTarget)
41 | if (laned.Lane != lanedTarget.Lane)
42 | continue;
43 | }
44 |
45 | switch (obj)
46 | {
47 | // We have to make sure DualHitParts from another lane don't block
48 | case DrawableDualHit dual:
49 | if (laned != null)
50 | yield return laned.Lane == LanedHitLane.Air ? dual.Air : dual.Ground;
51 | else
52 | yield return dual;
53 |
54 | break;
55 |
56 | case DrawableStarSheet sheet:
57 | yield return sheet.Head;
58 |
59 | break;
60 |
61 | default:
62 | yield return obj;
63 |
64 | break;
65 | }
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/RushReplayRecorder.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using System.Collections.Generic;
5 | using osu.Framework.Allocation;
6 | using osu.Game.Rulesets.Replays;
7 | using osu.Game.Rulesets.Rush.Input;
8 | using osu.Game.Rulesets.Rush.Replays;
9 | using osu.Game.Rulesets.UI;
10 | using osu.Game.Scoring;
11 | using osuTK;
12 |
13 | namespace osu.Game.Rulesets.Rush.UI
14 | {
15 | public partial class RushReplayRecorder : ReplayRecorder
16 | {
17 | [Resolved(canBeNull: true)]
18 | private DrawableRushRuleset drawableRuleset { get; set; }
19 |
20 | public RushReplayRecorder(Score target)
21 | : base(target)
22 | {
23 | }
24 |
25 | protected override ReplayFrame HandleFrame(Vector2 mousePosition, List actions, ReplayFrame previousFrame)
26 | {
27 | var frame = new RushReplayFrame(Time.Current, actions);
28 |
29 | if (drawableRuleset != null)
30 | frame.FeverActivationMode = drawableRuleset.FeverActivationMode;
31 |
32 | return frame;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/RushSettingsSubsection.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Allocation;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Localisation;
7 | using osu.Game.Overlays.Settings;
8 | using osu.Game.Rulesets.Rush.Configuration;
9 |
10 | namespace osu.Game.Rulesets.Rush.UI
11 | {
12 | public partial class RushSettingsSubsection : RulesetSettingsSubsection
13 | {
14 | private readonly Ruleset ruleset;
15 |
16 | protected new RushRulesetConfigManager Config => (RushRulesetConfigManager)base.Config;
17 |
18 | protected override LocalisableString Header => ruleset.Description;
19 |
20 | public RushSettingsSubsection(Ruleset ruleset)
21 | : base(ruleset)
22 | {
23 | this.ruleset = ruleset;
24 | }
25 |
26 | [BackgroundDependencyLoader]
27 | private void load()
28 | {
29 | Children = new Drawable[]
30 | {
31 | new SettingsEnumDropdown
32 | {
33 | LabelText = "Fever activation mode",
34 | Current = Config.GetBindable(RushRulesetSettings.FeverActivationMode)
35 | },
36 | };
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/UI/StarSheetHitExplosion.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Shane Woolcock. Licensed under the MIT Licence.
2 | // See the LICENCE file in the repository root for full licence text.
3 |
4 | using osu.Framework.Extensions.Color4Extensions;
5 | using osu.Framework.Graphics;
6 | using osu.Framework.Graphics.Pooling;
7 | using osu.Framework.Graphics.Shapes;
8 | using osu.Game.Rulesets.Objects.Drawables;
9 | using osu.Game.Rulesets.Rush.Objects.Drawables;
10 | using osu.Game.Rulesets.Rush.Objects.Drawables.Pieces;
11 | using osuTK;
12 |
13 | namespace osu.Game.Rulesets.Rush.UI
14 | {
15 | public partial class StarSheetHitExplosion : PoolableDrawable
16 | {
17 | private readonly StarSheetCapStarPiece explosionStar;
18 | private readonly Circle flashCircle;
19 |
20 | public StarSheetHitExplosion()
21 | {
22 | Origin = Anchor.Centre;
23 | Anchor = Anchor.CentreLeft;
24 |
25 | InternalChildren = new Drawable[]
26 | {
27 | explosionStar = new StarSheetCapStarPiece(),
28 | flashCircle = new Circle
29 | {
30 | Anchor = Anchor.Centre,
31 | Origin = Anchor.Centre,
32 | Alpha = 0.4f,
33 | RelativeSizeAxes = Axes.Both,
34 | Scale = new Vector2(0.5f),
35 | }
36 | };
37 | }
38 |
39 | public void Apply(DrawableHitObject drawable)
40 | {
41 | IDrawableLanedHit laned = (IDrawableLanedHit)drawable;
42 | Size = drawable.Size;
43 | flashCircle.Colour = laned.LaneAccentColour.Lighten(0.5f);
44 | }
45 |
46 | protected override void PrepareForUse()
47 | {
48 | base.PrepareForUse();
49 |
50 | explosionStar.ScaleTo(1)
51 | .ScaleTo(2f, RushPlayfield.HIT_EXPLOSION_DURATION)
52 | .FadeOutFromOne(RushPlayfield.HIT_EXPLOSION_DURATION)
53 | .Expire(true);
54 |
55 | flashCircle.ScaleTo(0.5f).FadeTo(0.4f)
56 | .ScaleTo(4f, RushPlayfield.HIT_EXPLOSION_DURATION / 2)
57 | .Then()
58 | .ScaleTo(0.5f, RushPlayfield.HIT_EXPLOSION_DURATION / 2)
59 | .FadeOut(RushPlayfield.HIT_EXPLOSION_DURATION / 2)
60 | .Expire(true);
61 |
62 | this.Delay(RushPlayfield.HIT_EXPLOSION_DURATION).Expire(true);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/osu.Game.Rulesets.Rush/osu.Game.Rulesets.Rush.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Debug;Release;Development
4 | net8.0
5 | Library
6 | AnyCPU
7 | osu.Game.Rulesets.Rush
8 |
9 |
10 | true
11 |
12 |
13 |
14 |
15 | osu.Game.Rulesets.Rush
16 | rush for osu!
17 |
18 |
19 |
20 |
21 | osu.Game.Rulesets.Rush-dev
22 | rush for osu! (development build)
23 |
24 |
25 |
26 |
27 |
31 |
32 | $(AssemblyName).$([System.String]::Copy(%(Identity)).Replace($([System.IO.Path]::DirectorySeparatorChar.ToString()), '.'))
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------