diff --git a/osu.Game.Rulesets.Sentakki/Mods/SentakkiModGori.cs b/osu.Game.Rulesets.Sentakki/Mods/SentakkiModGori.cs new file mode 100644 index 000000000..56d318f74 --- /dev/null +++ b/osu.Game.Rulesets.Sentakki/Mods/SentakkiModGori.cs @@ -0,0 +1,46 @@ +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Framework.Localisation; +using osu.Framework.Bindables; +using osu.Game.Rulesets.Scoring; +using osu.Game.Configuration; +using osu.Game.Rulesets.Sentakki.Objects.Drawables; +using osu.Framework.Graphics.Sprites; +using System; +using System.ComponentModel; + +namespace osu.Game.Rulesets.Sentakki.Mods; + +public class SentakkiModGori : Mod, IApplicableToDrawableHitObject +{ + public override string Name => "Gori"; + public override string Acronym => "GR"; + + public override bool HasImplementation => true; + public override double ScoreMultiplier => 1; + + public override IconUsage? Icon => FontAwesome.Solid.PooStorm; + + public override Type[] IncompatibleMods => new Type[]{ + typeof(ModAutoplay), + }; + + // TODO: LOCALISATION + public override LocalisableString Description => "You either hit it right, or you don't hit it at all."; + + [SettingSource("Lowest valid hit result", "The minimum HitResult that is accepted during gameplay. Anything below will be considered a miss.")] + public Bindable MaxHitResult { get; } = new Bindable(SentakkiHitResult.Perfect); + + public void ApplyToDrawableHitObject(DrawableHitObject drawable) + { + if (drawable is DrawableSentakkiHitObject d) + d.MinimumAcceptedHitResult = (HitResult)MaxHitResult.Value; + } + + public enum SentakkiHitResult + { + Great = 4, + Perfect = 5, + [Description("Critical Perfect")] Critical = 6, + } +} diff --git a/osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableSentakkiHitObject.cs b/osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableSentakkiHitObject.cs index 46e5cb53c..d13bbef97 100644 --- a/osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableSentakkiHitObject.cs +++ b/osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableSentakkiHitObject.cs @@ -5,6 +5,8 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Sentakki.UI; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Sentakki.Judgements; namespace osu.Game.Rulesets.Sentakki.Objects.Drawables { @@ -54,9 +56,28 @@ protected override void OnApply() AccentColour.BindTo(HitObject.ColourBindable); } + public HitResult MinimumAcceptedHitResult = HitResult.None; + protected void ApplyResult(HitResult result) { void resultApplication(JudgementResult r) => r.Type = result; + + // SentakkiModGori turns subpar judgements into misses + if (Result.Judgement is SentakkiJudgement) + { + if (MinimumAcceptedHitResult == HitResult.Perfect) // using the Perfect result to represent Crits + { + double absTimeOffset = Math.Abs(Time.Current - HitObject.GetEndTime()); + + if (absTimeOffset > 16) + result = Result.Judgement.MinResult; + } + else if (result < MinimumAcceptedHitResult) + { + result = Result.Judgement.MinResult; + } + } + ApplyResult(resultApplication); } diff --git a/osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs b/osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs index 80fc4649e..2c1d94650 100644 --- a/osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs +++ b/osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs @@ -86,6 +86,7 @@ public override IEnumerable GetModsFor(ModType type) new SentakkiModHardRock(), new MultiMod(new SentakkiModSuddenDeath(), new SentakkiModPerfect()), new MultiMod(new SentakkiModChallenge(), new SentakkiModAccuracyChallenge()), + new SentakkiModGori(), new MultiMod(new SentakkiModDoubleTime(), new SentakkiModNightcore()), new SentakkiModHidden(), };