2019-01-24 16:43:03 +08:00
|
|
|
|
// 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.
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
|
|
|
|
using System;
|
2018-08-03 20:03:11 +08:00
|
|
|
|
using System.Collections.Generic;
|
2019-09-02 17:31:33 +08:00
|
|
|
|
using System.Diagnostics;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using osu.Game.Rulesets.Mods;
|
2018-08-03 20:03:11 +08:00
|
|
|
|
using osu.Game.Rulesets.Objects.Types;
|
2018-08-16 17:18:15 +08:00
|
|
|
|
using osu.Game.Rulesets.Osu.Objects;
|
2018-08-03 20:03:11 +08:00
|
|
|
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
|
|
|
|
using osu.Game.Rulesets.UI;
|
|
|
|
|
using static osu.Game.Input.Handlers.ReplayInputHandler;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
|
|
|
|
namespace osu.Game.Rulesets.Osu.Mods
|
|
|
|
|
{
|
2019-07-02 06:47:39 +08:00
|
|
|
|
public class OsuModRelax : ModRelax, IUpdatableByPlayfield, IApplicableToDrawableRuleset<OsuHitObject>
|
2018-04-13 17:19:50 +08:00
|
|
|
|
{
|
|
|
|
|
public override string Description => @"You don't need to click. Give your clicking/tapping fingers a break from the heat of things.";
|
|
|
|
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
|
2018-08-03 20:03:11 +08:00
|
|
|
|
|
2020-02-14 15:58:56 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// How early before a hitobject's start time to trigger a hit.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private const float relax_leniency = 3;
|
|
|
|
|
|
2018-08-05 15:52:19 +08:00
|
|
|
|
public void Update(Playfield playfield)
|
2018-08-03 20:03:11 +08:00
|
|
|
|
{
|
2018-08-16 17:18:15 +08:00
|
|
|
|
bool requiresHold = false;
|
|
|
|
|
bool requiresHit = false;
|
2018-08-05 15:52:19 +08:00
|
|
|
|
|
2020-02-14 15:58:56 +08:00
|
|
|
|
double time = playfield.Clock.CurrentTime;
|
2018-08-03 20:03:11 +08:00
|
|
|
|
|
2020-02-14 15:58:56 +08:00
|
|
|
|
foreach (var h in playfield.HitObjectContainer.AliveObjects.OfType<DrawableOsuHitObject>())
|
2018-08-05 15:52:19 +08:00
|
|
|
|
{
|
2020-02-14 15:58:56 +08:00
|
|
|
|
// we are not yet close enough to the object.
|
|
|
|
|
if (time < h.HitObject.StartTime - relax_leniency)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// already hit or beyond the hittable end time.
|
|
|
|
|
if (h.IsHit || (h.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime))
|
2018-08-05 15:52:19 +08:00
|
|
|
|
continue;
|
2018-08-03 20:03:11 +08:00
|
|
|
|
|
2020-02-14 15:58:56 +08:00
|
|
|
|
switch (h)
|
|
|
|
|
{
|
|
|
|
|
case DrawableHitCircle _:
|
|
|
|
|
if (!h.IsHovered)
|
|
|
|
|
break;
|
2018-08-03 20:03:11 +08:00
|
|
|
|
|
2020-02-14 15:58:56 +08:00
|
|
|
|
Debug.Assert(h.HitObject.HitWindows != null);
|
|
|
|
|
requiresHit |= h.HitObject.HitWindows.CanBeHit(time - h.HitObject.StartTime);
|
|
|
|
|
break;
|
2018-08-03 20:03:11 +08:00
|
|
|
|
|
2020-02-14 15:58:56 +08:00
|
|
|
|
case DrawableSlider slider:
|
|
|
|
|
requiresHold |= slider.Ball.IsHovered || h.IsHovered;
|
|
|
|
|
break;
|
2018-08-03 20:03:11 +08:00
|
|
|
|
|
2020-02-14 15:58:56 +08:00
|
|
|
|
case DrawableSpinner _:
|
|
|
|
|
requiresHold = true;
|
|
|
|
|
break;
|
2019-09-02 17:31:33 +08:00
|
|
|
|
}
|
2018-08-03 20:03:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-16 17:18:15 +08:00
|
|
|
|
if (requiresHit)
|
2018-08-03 20:03:11 +08:00
|
|
|
|
{
|
2018-08-16 17:18:15 +08:00
|
|
|
|
addAction(false);
|
|
|
|
|
addAction(true);
|
2018-08-03 20:03:11 +08:00
|
|
|
|
}
|
2018-08-16 17:18:15 +08:00
|
|
|
|
|
|
|
|
|
addAction(requiresHold);
|
2018-08-03 20:03:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool wasHit;
|
|
|
|
|
private bool wasLeft;
|
|
|
|
|
|
2018-08-16 17:18:15 +08:00
|
|
|
|
private OsuInputManager osuInputManager;
|
|
|
|
|
|
|
|
|
|
private void addAction(bool hitting)
|
2018-08-03 20:03:11 +08:00
|
|
|
|
{
|
|
|
|
|
if (wasHit == hitting)
|
|
|
|
|
return;
|
2018-08-16 17:18:15 +08:00
|
|
|
|
|
2018-08-03 20:03:11 +08:00
|
|
|
|
wasHit = hitting;
|
|
|
|
|
|
2018-08-04 06:18:09 +08:00
|
|
|
|
var state = new ReplayState<OsuAction>
|
2018-08-03 20:03:11 +08:00
|
|
|
|
{
|
|
|
|
|
PressedActions = new List<OsuAction>()
|
|
|
|
|
};
|
2018-08-16 17:18:15 +08:00
|
|
|
|
|
2018-08-03 20:03:11 +08:00
|
|
|
|
if (hitting)
|
|
|
|
|
{
|
2018-08-04 06:18:09 +08:00
|
|
|
|
state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton);
|
2018-08-03 20:03:11 +08:00
|
|
|
|
wasLeft = !wasLeft;
|
|
|
|
|
}
|
2018-08-16 17:18:15 +08:00
|
|
|
|
|
2018-09-18 16:48:37 +08:00
|
|
|
|
state.Apply(osuInputManager.CurrentState, osuInputManager);
|
2018-08-16 17:18:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-20 10:22:34 +08:00
|
|
|
|
public void ApplyToDrawableRuleset(DrawableRuleset<OsuHitObject> drawableRuleset)
|
2018-08-16 17:18:15 +08:00
|
|
|
|
{
|
|
|
|
|
// grab the input manager for future use.
|
2019-03-20 10:22:34 +08:00
|
|
|
|
osuInputManager = (OsuInputManager)drawableRuleset.KeyBindingInputManager;
|
2018-08-17 18:33:14 +08:00
|
|
|
|
osuInputManager.AllowUserPresses = false;
|
2018-08-03 20:03:11 +08:00
|
|
|
|
}
|
2018-04-13 17:19:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|