2021-10-11 06:25:00 +00: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.
using System ;
2021-11-22 06:30:11 +00:00
using System.Linq ;
2021-10-11 06:25:00 +00:00
using JetBrains.Annotations ;
using Newtonsoft.Json ;
using osu.Framework.Testing ;
using osu.Game.Database ;
2021-11-19 10:07:21 +00:00
using osu.Game.Models ;
2021-11-19 10:24:07 +00:00
using osu.Game.Online.API.Requests.Responses ;
2022-03-20 02:01:32 +00:00
using osu.Game.Overlays.BeatmapSet.Scores ;
2021-10-11 06:25:00 +00:00
using osu.Game.Rulesets ;
2022-01-12 06:09:56 +00:00
using osu.Game.Scoring ;
2021-10-11 06:25:00 +00:00
using Realms ;
#nullable enable
2021-11-19 10:07:21 +00:00
namespace osu.Game.Beatmaps
2021-10-11 06:25:00 +00:00
{
/// <summary>
/// A single beatmap difficulty.
/// </summary>
[ExcludeFromDynamicCompile]
[Serializable]
[MapTo("Beatmap")]
2021-11-19 10:07:21 +00:00
public class BeatmapInfo : RealmObject , IHasGuidPrimaryKey , IBeatmapInfo , IEquatable < BeatmapInfo >
2021-10-11 06:25:00 +00:00
{
[PrimaryKey]
2022-01-18 13:51:45 +00:00
public Guid ID { get ; set ; }
2021-10-11 06:25:00 +00:00
public string DifficultyName { get ; set ; } = string . Empty ;
2022-01-18 13:51:45 +00:00
public RulesetInfo Ruleset { get ; set ; } = null ! ;
2021-10-11 06:25:00 +00:00
2022-01-18 13:51:45 +00:00
public BeatmapDifficulty Difficulty { get ; set ; } = null ! ;
2021-10-11 06:25:00 +00:00
2022-01-18 13:51:45 +00:00
public BeatmapMetadata Metadata { get ; set ; } = null ! ;
2022-01-10 10:23:43 +00:00
2022-01-20 08:09:31 +00:00
[JsonIgnore]
2022-01-12 09:05:25 +00:00
[Backlink(nameof(ScoreInfo.BeatmapInfo))]
2022-01-12 06:09:56 +00:00
public IQueryable < ScoreInfo > Scores { get ; } = null ! ;
2022-03-01 07:22:51 +00:00
public BeatmapUserSettings UserSettings { get ; set ; } = null ! ;
2022-01-18 13:51:45 +00:00
public BeatmapInfo ( RulesetInfo ? ruleset = null , BeatmapDifficulty ? difficulty = null , BeatmapMetadata ? metadata = null )
2022-01-10 10:23:43 +00:00
{
2022-01-18 13:51:45 +00:00
ID = Guid . NewGuid ( ) ;
Ruleset = ruleset ? ? new RulesetInfo
2022-01-17 05:40:00 +00:00
{
OnlineID = 0 ,
ShortName = @"osu" ,
Name = @"null placeholder ruleset"
} ;
2022-01-18 13:51:45 +00:00
Difficulty = difficulty ? ? new BeatmapDifficulty ( ) ;
Metadata = metadata ? ? new BeatmapMetadata ( ) ;
2022-03-01 07:22:51 +00:00
UserSettings = new BeatmapUserSettings ( ) ;
2022-01-18 13:51:45 +00:00
}
[UsedImplicitly]
private BeatmapInfo ( )
{
2022-01-10 10:23:43 +00:00
}
2021-10-11 06:25:00 +00:00
2021-11-19 10:07:21 +00:00
public BeatmapSetInfo ? BeatmapSet { get ; set ; }
2021-10-11 06:25:00 +00:00
2021-11-22 07:45:55 +00:00
[Ignored]
2021-12-21 07:09:32 +00:00
public RealmNamedFileUsage ? File = > BeatmapSet ? . Files . FirstOrDefault ( f = > f . File . Hash = = Hash ) ;
2021-11-22 06:30:11 +00:00
2022-01-18 14:25:30 +00:00
[Ignored]
2021-11-24 09:42:47 +00:00
public BeatmapOnlineStatus Status
2021-10-11 06:25:00 +00:00
{
2021-11-24 09:42:47 +00:00
get = > ( BeatmapOnlineStatus ) StatusInt ;
2021-10-11 06:25:00 +00:00
set = > StatusInt = ( int ) value ;
}
[MapTo(nameof(Status))]
2021-11-24 09:48:12 +00:00
public int StatusInt { get ; set ; } = ( int ) BeatmapOnlineStatus . None ;
2021-10-11 06:25:00 +00:00
2021-10-18 06:35:51 +00:00
[Indexed]
public int OnlineID { get ; set ; } = - 1 ;
2021-10-11 06:25:00 +00:00
public double Length { get ; set ; }
public double BPM { get ; set ; }
public string Hash { get ; set ; } = string . Empty ;
public double StarRating { get ; set ; }
public string MD5Hash { get ; set ; } = string . Empty ;
[JsonIgnore]
public bool Hidden { get ; set ; }
#region Properties we may not want persisted ( but also maybe no harm ? )
public double AudioLeadIn { get ; set ; }
public float StackLeniency { get ; set ; } = 0.7f ;
public bool SpecialStyle { get ; set ; }
public bool LetterboxInBreaks { get ; set ; }
2022-01-27 20:41:30 +00:00
public bool WidescreenStoryboard { get ; set ; } = true ;
2021-10-11 06:25:00 +00:00
public bool EpilepsyWarning { get ; set ; }
2022-01-27 20:41:30 +00:00
public bool SamplesMatchPlaybackRate { get ; set ; } = true ;
2021-10-11 06:25:00 +00:00
public double DistanceSpacing { get ; set ; }
public int BeatDivisor { get ; set ; }
public int GridSize { get ; set ; }
2022-01-25 08:31:05 +00:00
public double TimelineZoom { get ; set ; } = 1.0 ;
2021-10-11 06:25:00 +00:00
2021-12-14 12:00:19 +00:00
[Ignored]
2021-11-19 10:24:07 +00:00
public CountdownType Countdown { get ; set ; } = CountdownType . Normal ;
/// <summary>
/// The number of beats to move the countdown backwards (compared to its default location).
/// </summary>
public int CountdownOffset { get ; set ; }
2021-10-11 06:25:00 +00:00
#endregion
2021-11-19 10:07:21 +00:00
public bool Equals ( BeatmapInfo ? other )
2021-11-12 09:48:34 +00:00
{
if ( ReferenceEquals ( this , other ) ) return true ;
if ( other = = null ) return false ;
return ID = = other . ID ;
}
2021-11-19 10:07:21 +00:00
public bool Equals ( IBeatmapInfo ? other ) = > other is BeatmapInfo b & & Equals ( b ) ;
2021-11-16 03:25:37 +00:00
2021-11-19 10:07:21 +00:00
public bool AudioEquals ( BeatmapInfo ? other ) = > other ! = null
2021-11-19 10:24:07 +00:00
& & BeatmapSet ! = null
& & other . BeatmapSet ! = null
& & BeatmapSet . Hash = = other . BeatmapSet . Hash
& & Metadata . AudioFile = = other . Metadata . AudioFile ;
2021-10-11 06:25:00 +00:00
2021-11-19 10:07:21 +00:00
public bool BackgroundEquals ( BeatmapInfo ? other ) = > other ! = null
2021-11-19 10:24:07 +00:00
& & BeatmapSet ! = null
& & other . BeatmapSet ! = null
& & BeatmapSet . Hash = = other . BeatmapSet . Hash
& & Metadata . BackgroundFile = = other . Metadata . BackgroundFile ;
2021-10-11 06:25:00 +00:00
IBeatmapMetadataInfo IBeatmapInfo . Metadata = > Metadata ;
IBeatmapSetInfo ? IBeatmapInfo . BeatmapSet = > BeatmapSet ;
IRulesetInfo IBeatmapInfo . Ruleset = > Ruleset ;
IBeatmapDifficultyInfo IBeatmapInfo . Difficulty = > Difficulty ;
2021-11-19 10:24:07 +00:00
#region Compatibility properties
[Ignored]
2022-01-19 03:33:56 +00:00
[Obsolete("Use BeatmapInfo.Difficulty instead.")] // can be removed 20220719
2021-11-19 10:24:07 +00:00
public BeatmapDifficulty BaseDifficulty
{
get = > Difficulty ;
set = > Difficulty = value ;
}
[Ignored]
public string? Path = > File ? . Filename ;
[Ignored]
public APIBeatmap ? OnlineInfo { get ; set ; }
2022-03-20 02:01:32 +00:00
/// <summary>
/// The maximum achievable combo on this beatmap, populated for online info purposes only.
2022-03-20 13:30:28 +00:00
/// Todo: This should never be used nor exist, but is still relied on in <see cref="ScoresContainer.Scores"/> since <see cref="IBeatmapInfo"/> can't be used yet. For now this is obsoleted until it is removed.
2022-03-20 02:01:32 +00:00
/// </summary>
2021-11-19 10:24:07 +00:00
[Ignored]
2022-03-20 13:30:28 +00:00
[Obsolete("Use ScoreManager.GetMaximumAchievableComboAsync instead.")]
2021-11-19 10:24:07 +00:00
public int? MaxCombo { get ; set ; }
[Ignored]
public int [ ] Bookmarks { get ; set ; } = Array . Empty < int > ( ) ;
public int BeatmapVersion ;
2022-01-14 04:08:20 +00:00
public BeatmapInfo Clone ( ) = > ( BeatmapInfo ) this . Detach ( ) . MemberwiseClone ( ) ;
2021-11-19 10:24:07 +00:00
2022-01-10 03:36:11 +00:00
public override string ToString ( ) = > this . GetDisplayTitle ( ) ;
2022-01-07 05:17:22 +00:00
2021-11-19 10:24:07 +00:00
#endregion
2021-10-11 06:25:00 +00:00
}
}