1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-06 06:57:39 +08:00
osu-lazer/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs

116 lines
3.8 KiB
C#
Raw Normal View History

// 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;
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
{
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
/// <summary>
/// How early before a hitobject's start time to trigger a hit.
/// </summary>
private const float relax_leniency = 3;
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;
double time = playfield.Clock.CurrentTime;
2018-08-03 20:03:11 +08:00
foreach (var h in playfield.HitObjectContainer.AliveObjects.OfType<DrawableOsuHitObject>())
{
// 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))
continue;
2018-08-03 20:03:11 +08:00
switch (h)
{
case DrawableHitCircle circle:
handleHitCircle(circle);
break;
2018-08-03 20:03:11 +08:00
case DrawableSlider slider:
// Handles cases like "2B" beatmaps, where sliders may be overlapping and simply holding is not enough.
if (!slider.HeadCircle.IsHit)
handleHitCircle(slider.HeadCircle);
requiresHold |= slider.Ball.IsHovered || h.IsHovered;
break;
2018-08-03 20:03:11 +08:00
case DrawableSpinner _:
requiresHold = true;
break;
}
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);
void handleHitCircle(DrawableHitCircle circle)
{
if (!circle.IsHovered)
return;
Debug.Assert(circle.HitObject.HitWindows != null);
requiresHit |= circle.HitObject.HitWindows.CanBeHit(time - circle.HitObject.StartTime);
}
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
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
}
}