// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. #nullable enable using System; using osu.Framework.Bindables; using osu.Framework.Utils; using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.Scoring { public abstract class HealthProcessor : JudgementProcessor { /// /// Invoked when the is in a failed state. /// Return true if the fail was permitted. /// public event Func? Failed; /// /// Additional conditions on top of that cause a failing state. /// public event Func? FailConditions; /// /// The current health. /// public readonly BindableDouble Health = new BindableDouble(1) { MinValue = 0, MaxValue = 1 }; /// /// Whether this ScoreProcessor has already triggered the failed state. /// public bool HasFailed { get; private set; } protected override void ApplyResultInternal(JudgementResult result) { result.HealthAtJudgement = Health.Value; result.FailedAtJudgement = HasFailed; if (HasFailed) return; Health.Value += GetHealthIncreaseFor(result); if (!DefaultFailCondition && FailConditions?.Invoke(this, result) != true) return; if (Failed?.Invoke() != false) HasFailed = true; } protected override void RevertResultInternal(JudgementResult result) { Health.Value = result.HealthAtJudgement; // Todo: Revert HasFailed state with proper player support } /// /// Retrieves the health increase for a . /// /// The . /// The health increase. protected virtual double GetHealthIncreaseFor(JudgementResult result) => result.Judgement.HealthIncreaseFor(result); /// /// The default conditions for failing. /// protected virtual bool DefaultFailCondition => Precision.AlmostBigger(Health.MinValue, Health.Value); protected override void Reset(bool storeResults) { base.Reset(storeResults); Health.Value = 1; HasFailed = false; } } }