mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 21:02:54 +08:00
Merge branch 'master' into move-cache-logic-to-base-impl
This commit is contained in:
commit
9bb32f0914
@ -20,8 +20,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
|
||||
private TestDrawableSpinner drawableSpinner;
|
||||
|
||||
[TestCase(false)]
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void TestVariousSpinners(bool autoplay)
|
||||
{
|
||||
string term = autoplay ? "Hit" : "Miss";
|
||||
|
@ -19,98 +19,113 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
/// Legacy skinned spinner with two main spinning layers, one fixed overlay and one final spinning overlay.
|
||||
/// No background layer.
|
||||
/// </summary>
|
||||
public class LegacyNewStyleSpinner : CompositeDrawable
|
||||
public class LegacyNewStyleSpinner : LegacySpinner
|
||||
{
|
||||
private Sprite glow;
|
||||
private Sprite discBottom;
|
||||
private Sprite discTop;
|
||||
private Sprite spinningMiddle;
|
||||
private Sprite fixedMiddle;
|
||||
|
||||
private DrawableSpinner drawableSpinner;
|
||||
private readonly Color4 glowColour = new Color4(3, 151, 255, 255);
|
||||
|
||||
private const float final_scale = 0.625f;
|
||||
private Container scaleContainer;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ISkinSource source, DrawableHitObject drawableObject)
|
||||
private void load(ISkinSource source)
|
||||
{
|
||||
drawableSpinner = (DrawableSpinner)drawableObject;
|
||||
|
||||
Scale = new Vector2(final_scale);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
AddInternal(scaleContainer = new Container
|
||||
{
|
||||
discBottom = new Sprite
|
||||
Scale = new Vector2(SPRITE_SCALE),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-bottom")
|
||||
},
|
||||
discTop = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-top")
|
||||
},
|
||||
fixedMiddle = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-middle")
|
||||
},
|
||||
spinningMiddle = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-middle2")
|
||||
glow = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-glow"),
|
||||
Blending = BlendingParameters.Additive,
|
||||
Colour = glowColour,
|
||||
},
|
||||
discBottom = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-bottom")
|
||||
},
|
||||
discTop = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-top")
|
||||
},
|
||||
fixedMiddle = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-middle")
|
||||
},
|
||||
spinningMiddle = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-middle2")
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
protected override void UpdateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
|
||||
{
|
||||
base.LoadComplete();
|
||||
base.UpdateStateTransforms(drawableHitObject, state);
|
||||
|
||||
drawableSpinner.ApplyCustomUpdateState += updateStateTransforms;
|
||||
updateStateTransforms(drawableSpinner, drawableSpinner.State.Value);
|
||||
}
|
||||
|
||||
private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
|
||||
{
|
||||
if (!(drawableHitObject is DrawableSpinner d))
|
||||
return;
|
||||
|
||||
Spinner spinner = d.HitObject;
|
||||
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||
this.FadeOut();
|
||||
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2, true))
|
||||
this.FadeInFromZero(spinner.TimeFadeIn / 2);
|
||||
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||
switch (drawableHitObject)
|
||||
{
|
||||
fixedMiddle.FadeColour(Color4.White);
|
||||
case DrawableSpinner d:
|
||||
Spinner spinner = d.HitObject;
|
||||
|
||||
using (BeginDelayedSequence(spinner.TimePreempt, true))
|
||||
fixedMiddle.FadeColour(Color4.Red, spinner.Duration);
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||
this.FadeOut();
|
||||
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2, true))
|
||||
this.FadeInFromZero(spinner.TimeFadeIn / 2);
|
||||
|
||||
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt, true))
|
||||
{
|
||||
fixedMiddle.FadeColour(Color4.White);
|
||||
|
||||
using (BeginDelayedSequence(spinner.TimePreempt, true))
|
||||
fixedMiddle.FadeColour(Color4.Red, spinner.Duration);
|
||||
}
|
||||
|
||||
if (state == ArmedState.Hit)
|
||||
{
|
||||
using (BeginAbsoluteSequence(d.HitStateUpdateTime))
|
||||
glow.FadeOut(300);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DrawableSpinnerBonusTick _:
|
||||
if (state == ArmedState.Hit)
|
||||
glow.FlashColour(Color4.White, 200);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
spinningMiddle.Rotation = discTop.Rotation = drawableSpinner.RotationTracker.Rotation;
|
||||
spinningMiddle.Rotation = discTop.Rotation = DrawableSpinner.RotationTracker.Rotation;
|
||||
discBottom.Rotation = discTop.Rotation / 3;
|
||||
|
||||
Scale = new Vector2(final_scale * (0.8f + (float)Interpolation.ApplyEasing(Easing.Out, drawableSpinner.Progress) * 0.2f));
|
||||
}
|
||||
glow.Alpha = DrawableSpinner.Progress;
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (drawableSpinner != null)
|
||||
drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms;
|
||||
scaleContainer.Scale = new Vector2(SPRITE_SCALE * (0.8f + (float)Interpolation.ApplyEasing(Easing.Out, DrawableSpinner.Progress) * 0.2f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,28 +18,22 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
/// <summary>
|
||||
/// Legacy skinned spinner with one main spinning layer and a background layer.
|
||||
/// </summary>
|
||||
public class LegacyOldStyleSpinner : CompositeDrawable
|
||||
public class LegacyOldStyleSpinner : LegacySpinner
|
||||
{
|
||||
private DrawableSpinner drawableSpinner;
|
||||
private Sprite disc;
|
||||
private Sprite metreSprite;
|
||||
private Container metre;
|
||||
|
||||
private bool spinnerBlink;
|
||||
|
||||
private const float sprite_scale = 1 / 1.6f;
|
||||
private const float final_metre_height = 692 * sprite_scale;
|
||||
private const float final_metre_height = 692 * SPRITE_SCALE;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ISkinSource source, DrawableHitObject drawableObject)
|
||||
private void load(ISkinSource source)
|
||||
{
|
||||
spinnerBlink = source.GetConfig<OsuSkinConfiguration, bool>(OsuSkinConfiguration.SpinnerNoBlink)?.Value != true;
|
||||
|
||||
drawableSpinner = (DrawableSpinner)drawableObject;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
InternalChild = new Container
|
||||
AddInternal(new Container
|
||||
{
|
||||
// the old-style spinner relied heavily on absolute screen-space coordinate values.
|
||||
// wrap everything in a container simulating absolute coords to preserve alignment
|
||||
@ -55,14 +49,14 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-background"),
|
||||
Scale = new Vector2(sprite_scale)
|
||||
Scale = new Vector2(SPRITE_SCALE)
|
||||
},
|
||||
disc = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = source.GetTexture("spinner-circle"),
|
||||
Scale = new Vector2(sprite_scale)
|
||||
Scale = new Vector2(SPRITE_SCALE)
|
||||
},
|
||||
metre = new Container
|
||||
{
|
||||
@ -78,23 +72,17 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
Texture = source.GetTexture("spinner-metre"),
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
Scale = new Vector2(0.625f)
|
||||
Scale = new Vector2(SPRITE_SCALE)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
protected override void UpdateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
|
||||
{
|
||||
base.LoadComplete();
|
||||
base.UpdateStateTransforms(drawableHitObject, state);
|
||||
|
||||
drawableSpinner.ApplyCustomUpdateState += updateStateTransforms;
|
||||
updateStateTransforms(drawableSpinner, drawableSpinner.State.Value);
|
||||
}
|
||||
|
||||
private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
|
||||
{
|
||||
if (!(drawableHitObject is DrawableSpinner d))
|
||||
return;
|
||||
|
||||
@ -110,11 +98,11 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
disc.Rotation = drawableSpinner.RotationTracker.Rotation;
|
||||
disc.Rotation = DrawableSpinner.RotationTracker.Rotation;
|
||||
|
||||
// careful: need to call this exactly once for all calculations in a frame
|
||||
// as the function has a random factor in it
|
||||
var metreHeight = getMetreHeight(drawableSpinner.Progress);
|
||||
var metreHeight = getMetreHeight(DrawableSpinner.Progress);
|
||||
|
||||
// hack to make the metre blink up from below than down from above.
|
||||
// move down the container to be able to apply masking for the metre,
|
||||
@ -140,13 +128,5 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
|
||||
return (float)barCount / total_bars * final_metre_height;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (drawableSpinner != null)
|
||||
drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
84
osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs
Normal file
84
osu.Game.Rulesets.Osu/Skinning/LegacySpinner.cs
Normal file
@ -0,0 +1,84 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Skinning
|
||||
{
|
||||
public abstract class LegacySpinner : CompositeDrawable
|
||||
{
|
||||
protected const float SPRITE_SCALE = 0.625f;
|
||||
|
||||
protected DrawableSpinner DrawableSpinner { get; private set; }
|
||||
|
||||
private Sprite spin;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(DrawableHitObject drawableHitObject, ISkinSource source)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
DrawableSpinner = (DrawableSpinner)drawableHitObject;
|
||||
|
||||
AddRangeInternal(new[]
|
||||
{
|
||||
spin = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Depth = float.MinValue,
|
||||
Texture = source.GetTexture("spinner-spin"),
|
||||
Scale = new Vector2(SPRITE_SCALE),
|
||||
Y = 120 - 45 // offset temporarily to avoid overlapping default spin counter
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
DrawableSpinner.ApplyCustomUpdateState += UpdateStateTransforms;
|
||||
UpdateStateTransforms(DrawableSpinner, DrawableSpinner.State.Value);
|
||||
}
|
||||
|
||||
protected virtual void UpdateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
|
||||
{
|
||||
switch (drawableHitObject)
|
||||
{
|
||||
case DrawableSpinner d:
|
||||
double fadeOutLength = Math.Min(400, d.HitObject.Duration);
|
||||
|
||||
using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime - fadeOutLength, true))
|
||||
spin.FadeOutFromOne(fadeOutLength);
|
||||
|
||||
break;
|
||||
|
||||
case DrawableSpinnerTick d:
|
||||
if (state == ArmedState.Hit)
|
||||
{
|
||||
using (BeginAbsoluteSequence(d.HitStateUpdateTime, true))
|
||||
spin.FadeOut(300);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (DrawableSpinner != null)
|
||||
DrawableSpinner.ApplyCustomUpdateState -= UpdateStateTransforms;
|
||||
}
|
||||
}
|
||||
}
|
@ -250,7 +250,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
public void EndPlay(int beatmapId)
|
||||
{
|
||||
((ISpectatorClient)this).UserFinishedPlaying((int)StreamingUser.Id, new SpectatorState
|
||||
((ISpectatorClient)this).UserFinishedPlaying(StreamingUser.Id, new SpectatorState
|
||||
{
|
||||
BeatmapID = beatmapId,
|
||||
RulesetID = 0,
|
||||
@ -273,7 +273,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
}
|
||||
|
||||
var bundle = new FrameDataBundle(frames);
|
||||
((ISpectatorClient)this).UserSentFrames((int)StreamingUser.Id, bundle);
|
||||
((ISpectatorClient)this).UserSentFrames(StreamingUser.Id, bundle);
|
||||
|
||||
if (!sentState)
|
||||
sendState(beatmapId);
|
||||
@ -293,7 +293,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
private void sendState(int beatmapId)
|
||||
{
|
||||
sentState = true;
|
||||
((ISpectatorClient)this).UserBeganPlaying((int)StreamingUser.Id, new SpectatorState
|
||||
((ISpectatorClient)this).UserBeganPlaying(StreamingUser.Id, new SpectatorState
|
||||
{
|
||||
BeatmapID = beatmapId,
|
||||
RulesetID = 0,
|
||||
|
@ -277,7 +277,7 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
userId.Value = user.Id.ToString();
|
||||
userId.BindValueChanged(idString =>
|
||||
{
|
||||
long.TryParse(idString.NewValue, out var parsed);
|
||||
int.TryParse(idString.NewValue, out var parsed);
|
||||
|
||||
user.Id = parsed;
|
||||
|
||||
|
@ -61,7 +61,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
private int[] ratings { get; set; }
|
||||
|
||||
[JsonProperty(@"user_id")]
|
||||
private long creatorId
|
||||
private int creatorId
|
||||
{
|
||||
set => Author.Id = value;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
public string OsuUsername { get; set; }
|
||||
|
||||
[JsonProperty("user_id")]
|
||||
public long? UserId { get; set; }
|
||||
public int? UserId { get; set; }
|
||||
|
||||
[JsonProperty("user_url")]
|
||||
public string UserUrl { get; set; }
|
||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Online.Chat
|
||||
public readonly ObservableCollection<User> Users = new ObservableCollection<User>();
|
||||
|
||||
[JsonProperty(@"users")]
|
||||
private long[] userIds
|
||||
private int[] userIds
|
||||
{
|
||||
set
|
||||
{
|
||||
|
@ -278,7 +278,7 @@ namespace osu.Game
|
||||
break;
|
||||
|
||||
case LinkAction.OpenUserProfile:
|
||||
if (long.TryParse(link.Argument, out long userId))
|
||||
if (int.TryParse(link.Argument, out int userId))
|
||||
ShowUser(userId);
|
||||
break;
|
||||
|
||||
@ -321,7 +321,7 @@ namespace osu.Game
|
||||
/// Show a user's profile as an overlay.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user to display.</param>
|
||||
public void ShowUser(long userId) => waitForReady(() => userProfile, _ => userProfile.ShowUser(userId));
|
||||
public void ShowUser(int userId) => waitForReady(() => userProfile, _ => userProfile.ShowUser(userId));
|
||||
|
||||
/// <summary>
|
||||
/// Show a beatmap's set as an overlay, displaying the given beatmap.
|
||||
|
@ -59,7 +59,7 @@ namespace osu.Game.Overlays.Dashboard
|
||||
var request = new GetUserRequest(u);
|
||||
request.Success += user => Schedule(() =>
|
||||
{
|
||||
if (playingUsers.Contains((int)user.Id))
|
||||
if (playingUsers.Contains(user.Id))
|
||||
userFlow.Add(createUserPanel(user));
|
||||
});
|
||||
api.Queue(request);
|
||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
}
|
||||
|
||||
public void ShowUser(long userId) => ShowUser(new User { Id = userId });
|
||||
public void ShowUser(int userId) => ShowUser(new User { Id = userId });
|
||||
|
||||
public void ShowUser(User user, bool fetchOnline = true)
|
||||
{
|
||||
|
@ -546,7 +546,11 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
// Ensure that the judgement is given a valid time offset, because this may not get set by the caller
|
||||
var endTime = HitObject.GetEndTime();
|
||||
|
||||
Result.TimeOffset = Math.Min(HitObject.HitWindows.WindowFor(HitResult.Miss), Time.Current - endTime);
|
||||
Result.TimeOffset = Time.Current - endTime;
|
||||
|
||||
double missWindow = HitObject.HitWindows.WindowFor(HitResult.Miss);
|
||||
if (missWindow > 0)
|
||||
Result.TimeOffset = Math.Min(Result.TimeOffset, missWindow);
|
||||
|
||||
if (Result.HasResult)
|
||||
updateState(Result.IsHit ? ArmedState.Hit : ArmedState.Miss);
|
||||
|
@ -123,7 +123,7 @@ namespace osu.Game.Scoring
|
||||
|
||||
[JsonIgnore]
|
||||
[Column("UserID")]
|
||||
public long? UserID
|
||||
public int? UserID
|
||||
{
|
||||
get => User?.Id ?? 1;
|
||||
set
|
||||
|
@ -182,7 +182,7 @@ namespace osu.Game.Screens.Play
|
||||
spectatorStreaming.OnUserFinishedPlaying += userFinishedPlaying;
|
||||
spectatorStreaming.OnNewFrames += userSentFrames;
|
||||
|
||||
spectatorStreaming.WatchUser((int)targetUser.Id);
|
||||
spectatorStreaming.WatchUser(targetUser.Id);
|
||||
|
||||
managerUpdated = beatmaps.ItemUpdated.GetBoundCopy();
|
||||
managerUpdated.BindValueChanged(beatmapUpdated);
|
||||
@ -353,7 +353,7 @@ namespace osu.Game.Screens.Play
|
||||
spectatorStreaming.OnUserFinishedPlaying -= userFinishedPlaying;
|
||||
spectatorStreaming.OnNewFrames -= userSentFrames;
|
||||
|
||||
spectatorStreaming.StopWatchingUser((int)targetUser.Id);
|
||||
spectatorStreaming.StopWatchingUser(targetUser.Id);
|
||||
}
|
||||
|
||||
managerUpdated?.UnbindAll();
|
||||
|
@ -12,7 +12,7 @@ namespace osu.Game.Users
|
||||
public class User : IEquatable<User>
|
||||
{
|
||||
[JsonProperty(@"id")]
|
||||
public long Id = 1;
|
||||
public int Id = 1;
|
||||
|
||||
[JsonProperty(@"join_date")]
|
||||
public DateTimeOffset JoinDate;
|
||||
|
Loading…
Reference in New Issue
Block a user