private void addAction(bool hitting, bool hardhit = false) { if (wasHit == hitting) { return; } wasHit = hitting; var state = new ReplayState <TauAction> { PressedActions = new List <TauAction>() }; if (hitting) { if (hardhit) { state.PressedActions.Add(TauAction.HardButton); } else { state.PressedActions.Add(wasLeft ? TauAction.LeftButton : TauAction.RightButton); wasLeft = !wasLeft; } } state.Apply(tauInputManager.CurrentState, tauInputManager); }
private void addAction(bool hitting) { if (wasHit == hitting) { return; } wasHit = hitting; var state = new ReplayState <OsuAction> { PressedActions = new List <OsuAction>() }; if (hitting) { state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton); wasLeft = !wasLeft; } state.Apply(osuInputManager.CurrentState, osuInputManager); }
public void Update(Playfield playfield) { if (hasReplay) { return; } bool requiresHold = false; bool requiresHit = false; double time = playfield.Clock.CurrentTime; 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 IHasDuration hasEnd && time > hasEnd.EndTime)) { continue; } switch (h) { case DrawableHitCircle circle: handleHitCircle(circle); break; 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; case DrawableSpinner _: requiresHold = true; break; } } if (requiresHit) { changeState(false); changeState(true); } if (requiresHold) { changeState(true); } else if (isDownState && time - lastStateChangeTime > AutoGenerator.KEY_UP_DELAY) { changeState(false); } void handleHitCircle(DrawableHitCircle circle) { if (!circle.HitArea.IsHovered) { return; } Debug.Assert(circle.HitObject.HitWindows != null); requiresHit |= circle.HitObject.HitWindows.CanBeHit(time - circle.HitObject.StartTime); } void changeState(bool down) { if (isDownState == down) { return; } isDownState = down; lastStateChangeTime = time; state = new ReplayState <OsuAction> { PressedActions = new List <OsuAction>() }; if (down) { state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton); wasLeft = !wasLeft; } state?.Apply(osuInputManager.CurrentState, osuInputManager); } }
public void Update(Playfield playfield) { if (hasReplay) { return; } bool requiresHold = false; bool requiresHit = false; double time = playfield.Clock.CurrentTime; foreach (var h in playfield.HitObjectContainer.AliveObjects.OfType <DrawableSentakkiHitObject>()) { // 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; } switch (h) { case DrawableTap tap: if (tap.HitArea.IsHovered) { Debug.Assert(tap.HitObject.HitWindows != null); requiresHit |= tap.HitObject.HitWindows.CanBeHit(time - tap.HitObject.StartTime); } break; case DrawableHold hold: requiresHold |= hold.HitArea.IsHovered || h.IsHovered; break; case DrawableTouchHold _: requiresHold = true; break; } } if (requiresHit) { changeState(false); changeState(true); } if (requiresHold) { changeState(true); } else if (isDownState && time - lastStateChangeTime > AutoGenerator.KEY_UP_DELAY) { changeState(false); } void changeState(bool down) { if (isDownState == down) { return; } isDownState = down; lastStateChangeTime = time; state = new ReplayState <SentakkiAction> { PressedActions = new List <SentakkiAction>() }; if (down) { state.PressedActions.Add(wasLeft ? SentakkiAction.Button1 : SentakkiAction.Button2); wasLeft = !wasLeft; } state?.Apply(sentakkiInputManager.CurrentState, sentakkiInputManager); } }