-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Add Bad Apple mod into the osu!catch ruleset
#37065
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
96edf55
2df8462
7c669bd
e2bb407
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. | ||
| // See the LICENCE file in the repository root for full licence text. | ||
|
|
||
| using NUnit.Framework; | ||
| using osu.Game.Rulesets.Catch.Mods; | ||
| using osu.Game.Tests.Visual; | ||
|
|
||
| namespace osu.Game.Rulesets.Catch.Tests.Mods | ||
| { | ||
| public partial class TestSceneCatchModBadApple : ModTestScene | ||
| { | ||
| protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); | ||
|
|
||
| [Test] | ||
| public void TestBadApple() => CreateModTest(new ModTestData | ||
| { | ||
| Mod = new CatchModBadApple(), | ||
| PassCondition = () => true | ||
| }); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. | ||
| // See the LICENCE file in the repository root for full licence text. | ||
|
|
||
| using System; | ||
| using osu.Framework.Bindables; | ||
| using osu.Framework.Localisation; | ||
| using osu.Framework.Audio; | ||
| using osu.Game.Configuration; | ||
| using osu.Game.Rulesets.Catch.Objects; | ||
| using osu.Game.Rulesets.Catch.Objects.Drawables; | ||
| using osu.Game.Rulesets.Catch.UI; | ||
| using osu.Game.Rulesets.Objects.Drawables; | ||
| using osu.Game.Rulesets.Mods; | ||
| using osu.Game.Rulesets.UI; | ||
| using osu.Framework.Graphics; | ||
|
|
||
| namespace osu.Game.Rulesets.Catch.Mods | ||
| { | ||
| public class CatchModBadApple : Mod, IApplicableToDrawableHitObject, IApplicableToDrawableRuleset<CatchHitObject>, IUpdatableByPlayfield | ||
| { | ||
| public override string Name => "Bad Apple"; | ||
| public override LocalisableString Description => "The fruit has gone bad... dodge it!"; | ||
| public override double ScoreMultiplier => 1; | ||
| public override string Acronym => "BA"; | ||
| public override Type[] IncompatibleMods => new[] { typeof(CatchModAutoplay) }; | ||
|
|
||
| [SettingSource("Mute hit sounds", "Hit sounds become muted.")] | ||
| public BindableBool AffectsHitSounds { get; } = new BindableBool(true); | ||
|
|
||
| private Catcher catcher = null!; | ||
| private readonly BindableNumber<double> hitSoundVolume = new BindableDouble(0); | ||
|
|
||
| public void ApplyToDrawableRuleset(DrawableRuleset<CatchHitObject> drawableRuleset) | ||
| { | ||
| catcher = ((CatchPlayfield)drawableRuleset.Playfield).Catcher; | ||
|
|
||
| // Don't show caught fruits as they aren't technically being caught. | ||
| catcher.CatchFruitOnPlate = false; | ||
|
|
||
| if (AffectsHitSounds.Value) | ||
| { | ||
| drawableRuleset.Audio.AddAdjustment(AdjustableProperty.Volume, hitSoundVolume); | ||
| } | ||
| } | ||
|
|
||
| public void ApplyToDrawableHitObject(DrawableHitObject drawable) | ||
| { | ||
| if (drawable is DrawableCatchHitObject catchHitObject) | ||
| { | ||
| catchHitObject.CheckPosition = hitObject => !catcher.CanCatch(hitObject); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get what this is going for, but the visual effects of this change mean that this mod looks terrible on argon and legacy skins, and a little less terrible on triangles. See video below. Fruit disappear instantly on miss and slowly fade out on catch which is all types of wrong IMO. Screen.Recording.2026-03-23.at.08.48.18.mov
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll try to change the behaviour and see what I can do
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In terms of constructive feedback, in a perfect world I think dodged fruits could explode in some way to indicate hit, while missed fruits... not sure. Maybe missed fruits could stay on the catcher? Could be a fun idea as a way of punishing the player for catches, but maybe overly punishing if you catch too much. Might not be very easy to pull any of that though.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2026-03-24.23-35-41.mp4For now this is how I was able to get it to work, i should probably delete the hitlightning too since its kinda off personally but im not sure |
||
| } | ||
|
|
||
| drawable.ApplyCustomUpdateState += (dho, state) => | ||
| { | ||
| // Keep the existing transforms when hit. | ||
| if (state is not ArmedState.Hit) | ||
| return; | ||
|
|
||
| // When "hit", the DHO is faded out, so to let fruits fall after being caught we fade them back in. | ||
| dho.FadeIn(); | ||
| }; | ||
| } | ||
| public void Update(Playfield playfield) | ||
Check warningCode scanning / InspectCode Incorrect blank lines: Blank lines are missing elsewhere Warning
Blank lines are missing, expected minimum 1 instead of 0
|
||
| { | ||
| // Block hyperdashing to avoid hyperdashes when two objects appear at the same time. | ||
| catcher.SetHyperDashState(1, -1); | ||
|
Comment on lines
+65
to
+66
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is pretty terrible and in general I don't know that having hyperfruit at all here is a good idea. Rather than doing whatever this is doing, I'd implement
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea that makes more sense, will do |
||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mod should be in "Conversion" category since it fundamentally alters goals of gameplay. This has tagging / medal implications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yea I guess that makes sense, will adjust