1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-22 16:16:07 +08:00

Merge pull request #31924 from peppy/fix-kiai-fountains-rapid-fire

Fix kiai fountains sometimes not displaying when they should
This commit is contained in:
Bartłomiej Dach 2025-02-18 11:27:02 +01:00 committed by GitHub
commit 98ff4e054a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 43 deletions

View File

@ -73,6 +73,16 @@ namespace osu.Game.Graphics.Containers
/// </summary>
protected bool IsBeatSyncedWithTrack { get; private set; }
/// <summary>
/// The most valid timing point, updated every frame.
/// </summary>
protected TimingControlPoint TimingPoint { get; private set; } = TimingControlPoint.DEFAULT;
/// <summary>
/// The most valid effect point, updated every frame.
/// </summary>
protected EffectControlPoint EffectPoint { get; private set; } = EffectControlPoint.DEFAULT;
[Resolved]
protected IBeatSyncProvider BeatSyncSource { get; private set; } = null!;
@ -82,9 +92,6 @@ namespace osu.Game.Graphics.Containers
protected override void Update()
{
TimingControlPoint timingPoint;
EffectControlPoint effectPoint;
IsBeatSyncedWithTrack = BeatSyncSource.Clock.IsRunning;
double currentTrackTime;
@ -102,8 +109,8 @@ namespace osu.Game.Graphics.Containers
currentTrackTime = BeatSyncSource.Clock.CurrentTime + early;
timingPoint = BeatSyncSource.ControlPoints?.TimingPointAt(currentTrackTime) ?? TimingControlPoint.DEFAULT;
effectPoint = BeatSyncSource.ControlPoints?.EffectPointAt(currentTrackTime) ?? EffectControlPoint.DEFAULT;
TimingPoint = BeatSyncSource.ControlPoints?.TimingPointAt(currentTrackTime) ?? TimingControlPoint.DEFAULT;
EffectPoint = BeatSyncSource.ControlPoints?.EffectPointAt(currentTrackTime) ?? EffectControlPoint.DEFAULT;
}
else
{
@ -111,28 +118,28 @@ namespace osu.Game.Graphics.Containers
// we still want to show an idle animation, so use this container's time instead.
currentTrackTime = Clock.CurrentTime + EarlyActivationMilliseconds;
timingPoint = TimingControlPoint.DEFAULT;
effectPoint = EffectControlPoint.DEFAULT;
TimingPoint = TimingControlPoint.DEFAULT;
EffectPoint = EffectControlPoint.DEFAULT;
}
double beatLength = timingPoint.BeatLength / Divisor;
double beatLength = TimingPoint.BeatLength / Divisor;
while (beatLength < MinimumBeatLength)
beatLength *= 2;
int beatIndex = (int)((currentTrackTime - timingPoint.Time) / beatLength) - (timingPoint.OmitFirstBarLine ? 1 : 0);
int beatIndex = (int)((currentTrackTime - TimingPoint.Time) / beatLength) - (TimingPoint.OmitFirstBarLine ? 1 : 0);
// The beats before the start of the first control point are off by 1, this should do the trick
if (currentTrackTime < timingPoint.Time)
if (currentTrackTime < TimingPoint.Time)
beatIndex--;
TimeUntilNextBeat = (timingPoint.Time - currentTrackTime) % beatLength;
TimeUntilNextBeat = (TimingPoint.Time - currentTrackTime) % beatLength;
if (TimeUntilNextBeat <= 0)
TimeUntilNextBeat += beatLength;
TimeSinceLastBeat = beatLength - TimeUntilNextBeat;
if (ReferenceEquals(timingPoint, lastTimingPoint) && beatIndex == lastBeat)
if (ReferenceEquals(TimingPoint, lastTimingPoint) && beatIndex == lastBeat)
return;
// as this event is sometimes used for sound triggers where `BeginDelayedSequence` has no effect, avoid firing it if too far away from the beat.
@ -140,13 +147,13 @@ namespace osu.Game.Graphics.Containers
if (AllowMistimedEventFiring || Math.Abs(TimeSinceLastBeat) < MISTIMED_ALLOWANCE)
{
using (BeginDelayedSequence(-TimeSinceLastBeat))
OnNewBeat(beatIndex, timingPoint, effectPoint, BeatSyncSource.CurrentAmplitudes);
OnNewBeat(beatIndex, TimingPoint, EffectPoint, BeatSyncSource.CurrentAmplitudes);
}
lastBeat = beatIndex;
lastTimingPoint = timingPoint;
lastTimingPoint = TimingPoint;
IsKiaiTime = effectPoint.KiaiMode;
IsKiaiTime = EffectPoint.KiaiMode;
}
}
}

View File

@ -3,10 +3,8 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
namespace osu.Game.Screens.Menu
@ -40,27 +38,22 @@ namespace osu.Game.Screens.Menu
private bool isTriggered;
private double? lastTrigger;
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
protected override void Update()
{
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
base.Update();
if (effectPoint.KiaiMode && !isTriggered)
if (EffectPoint.KiaiMode && !isTriggered)
{
bool isNearEffectPoint = Math.Abs(BeatSyncSource.Clock.CurrentTime - effectPoint.Time) < 500;
bool isNearEffectPoint = Math.Abs(BeatSyncSource.Clock.CurrentTime - EffectPoint.Time) < 500;
if (isNearEffectPoint)
Shoot();
}
isTriggered = effectPoint.KiaiMode;
isTriggered = EffectPoint.KiaiMode;
}
public void Shoot()
{
if (lastTrigger != null && Clock.CurrentTime - lastTrigger < 500)
return;
int direction = RNG.Next(-1, 2);
switch (direction)
@ -80,8 +73,6 @@ namespace osu.Game.Screens.Menu
rightFountain.Shoot(1);
break;
}
lastTrigger = Clock.CurrentTime;
}
}
}

View File

@ -1,15 +1,13 @@
// 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.
#nullable disable
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Logging;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
using osu.Game.Screens.Menu;
@ -48,33 +46,28 @@ namespace osu.Game.Screens.Play
private bool isTriggered;
private double? lastTrigger;
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
protected override void Update()
{
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
base.Update();
if (!kiaiStarFountains.Value)
return;
if (effectPoint.KiaiMode && !isTriggered)
if (EffectPoint.KiaiMode && !isTriggered)
{
bool isNearEffectPoint = Math.Abs(BeatSyncSource.Clock.CurrentTime - effectPoint.Time) < 500;
Logger.Log("shooting");
bool isNearEffectPoint = Math.Abs(BeatSyncSource.Clock.CurrentTime - EffectPoint.Time) < 500;
if (isNearEffectPoint)
Shoot();
}
isTriggered = effectPoint.KiaiMode;
isTriggered = EffectPoint.KiaiMode;
}
public void Shoot()
{
if (lastTrigger != null && Clock.CurrentTime - lastTrigger < 500)
return;
leftFountain.Shoot(1);
rightFountain.Shoot(-1);
lastTrigger = Clock.CurrentTime;
}
public partial class GameplayStarFountain : StarFountain