Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Quaver.API/Enums/HitObjectType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Quaver.API.Enums
{
/// <summary>
/// Indicates the type of a hit object
/// </summary>
public enum HitObjectType
{
Normal, // Regular hit object. It should be hit normally.
Mine // A mine object. It should not be hit, and hitting it will result in a miss.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public DifficultyProcessorKeys(Qua map, StrainConstants constants, ModIdentifier
StrainConstants = (StrainConstantsKeys)constants;

// Don't bother calculating map difficulty if there's less than 2 hit objects
if (map.HitObjects.Count < 2)
if (map.DifficultyContributingHitObjects < 2)
return;

// Solve for difficulty
Expand Down Expand Up @@ -203,6 +203,8 @@ private void ComputeBaseStrainStates(float rate, Hand assumeHand)
{
if (Map.HasScratchKey && Map.HitObjects[i].Lane == Map.GetKeyCount())
continue;
if (Map.HitObjects[i].Type == HitObjectType.Mine)
continue;

var curHitOb = new StrainSolverHitObject(Map.HitObjects[i]);
var curStrainData = new StrainSolverData(curHitOb, rate);
Expand Down Expand Up @@ -675,7 +677,7 @@ private float CalculateOverallDifficulty()
private void ComputeNoteDensityData(float rate)
{
//MapLength = Qua.Length;
AverageNoteDensity = SECONDS_TO_MILLISECONDS * Map.HitObjects.Count / (Map.Length * (-.5f * rate + 1.5f));
AverageNoteDensity = SECONDS_TO_MILLISECONDS * Map.DifficultyContributingHitObjects / (Map.Length * (-.5f * rate + 1.5f));
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Quaver.API/Maps/Processors/Scoring/ScoreProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public ScoreProcessor(Replay replay, JudgementWindows windows = null)
/// <summary>
/// Adds a judgement to the score and recalculates the score.
/// </summary>
public abstract void CalculateScore(Judgement judgement, bool isLongNoteRelease = false);
public abstract void CalculateScore(Judgement judgement, bool isLongNoteRelease = false, bool isMine = false);

/// <summary>
/// Calculates the accuracy of the current play session.
Expand Down
32 changes: 17 additions & 15 deletions Quaver.API/Maps/Processors/Scoring/ScoreProcessorKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Quaver.API.Maps.Processors.Scoring.Data;
using Quaver.API.Maps.Processors.Scoring.Multiplayer;
using Quaver.API.Replays;
using HitObjectType = Quaver.API.Enums.HitObjectType;

namespace Quaver.API.Maps.Processors.Scoring
{
Expand Down Expand Up @@ -173,7 +174,9 @@ public ScoreProcessorKeys(Replay replay, JudgementWindows windows = null) : base
/// <param name="hitDifference"></param>
/// <param name="keyPressType"></param>
/// <param name="calculateAllStats"></param>
public Judgement CalculateScore(int hitDifference, KeyPressType keyPressType, bool calculateAllStats = true)
/// <param name="isMine"></param>
public Judgement CalculateScore(int hitDifference, KeyPressType keyPressType, bool calculateAllStats = true,
bool isMine = false)
{
var absoluteDifference = 0;

Expand Down Expand Up @@ -222,18 +225,25 @@ public Judgement CalculateScore(int hitDifference, KeyPressType keyPressType, bo
return judgement;

if (calculateAllStats)
CalculateScore(judgement, keyPressType == KeyPressType.Release);
CalculateScore(judgement, keyPressType == KeyPressType.Release, isMine);

return judgement;
}

public void CalculateScore(HitStat hitStat)
{
CalculateScore(hitStat.Judgement, hitStat.KeyPressType == KeyPressType.Release,
hitStat.HitObject.Type is HitObjectType.Mine);
}

/// <inheritdoc />
/// <summary>
/// Calculate Score and Health increase/decrease with a given judgement.
/// </summary>
/// <param name="judgement"></param>
/// <param name="isLongNoteRelease"></param>
public override void CalculateScore(Judgement judgement, bool isLongNoteRelease = false)
/// <param name="isMine"></param>
public override void CalculateScore(Judgement judgement, bool isLongNoteRelease = false, bool isMine = false)
{
// Update Judgement count
CurrentJudgements[judgement]++;
Expand All @@ -257,7 +267,9 @@ public override void CalculateScore(Judgement judgement, bool isLongNoteRelease
MultiplierCount++;

// Add to the combo since the user hit.
Combo++;
// Only do this when the note is not a mine (so it is a regular note)
if (!isMine)
Combo++;

// Set the max combo if applicable.
if (Combo > MaxCombo)
Expand Down Expand Up @@ -372,17 +384,7 @@ protected override void InitializeHealthWeighting()
/// <returns></returns>
public int GetTotalJudgementCount()
{
var judgements = 0;

foreach (var o in Map.HitObjects)
{
if (o.IsLongNote)
judgements += 2;
else
judgements++;
}

return judgements;
return Map.HitObjects.Sum(o => o.JudgementCount);
}

/// <summary>
Expand Down
42 changes: 38 additions & 4 deletions Quaver.API/Maps/Qua.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ namespace Quaver.API.Maps
public class Qua
{
// 0 versioning added
// 1 mines
public int QuaVersion { get; set; } = 0;

// Max supported version by this client
// This should be incremented whenever breaking changes are made to quas
// DetermineMinimumQuaVersion() should also be updated to allow older clients to load maps without new features
public const int CurrentQuaVersion = 0;
public const int CurrentQuaVersion = 1;

/// <summary>
/// The name of the audio file
Expand Down Expand Up @@ -193,6 +194,19 @@ public List<ScrollSpeedFactorInfo> ScrollSpeedFactors
/// </summary>
public List<HitObjectInfo> HitObjects { get; private set; } = new List<HitObjectInfo>();

/// <summary>
/// Number of mines in the map
/// </summary>
[YamlIgnore]
public int MineCount => HitObjects.Count(x => x.Type is HitObjectType.Mine);

/// <summary>
/// Number of notes counted for diffcalc.
/// Currently, it's every note except mines
/// </summary>
[YamlIgnore]
public int DifficultyContributingHitObjects => HitObjects.Count - MineCount;

public Dictionary<string, TimingGroup> TimingGroups { get; private set; } =
new Dictionary<string, TimingGroup>();

Expand Down Expand Up @@ -314,7 +328,19 @@ private bool CompareTimingGroups(Dictionary<string, TimingGroup> other)

public int DetermineMinimumQuaVersion()
{
return 0;
int ver = 0;

void Check(int v, Func<bool> f)
{
if (ver < v && f())
{
ver = v;
}
}

Check(1, () => MineCount != 0);

return ver;
}

/// <summary>
Expand Down Expand Up @@ -373,7 +399,8 @@ static HitObjectInfo SerializableHitObject(HitObjectInfo obj) =>
.Select(x => new KeySoundInfo { Sample = x.Sample, Volume = x.Volume == 100 ? 0 : x.Volume })
.ToList(),
Lane = obj.Lane, StartTime = obj.StartTime,
TimingGroup = obj.TimingGroup == DefaultScrollGroupId ? null : obj.TimingGroup
TimingGroup = obj.TimingGroup == DefaultScrollGroupId ? null : obj.TimingGroup,
Type = obj.Type
};

static SoundEffectInfo SerializableSoundEffect(SoundEffectInfo x) =>
Expand Down Expand Up @@ -1117,8 +1144,15 @@ public HitObjectInfo GetHitObjectAtJudgementIndex(int index)

// ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
foreach (var h in HitObjects)
if (total++ == index || (h.IsLongNote && total++ == index))
{
var judgementCount = h.JudgementCount;
if (total <= index && index < total + judgementCount)
{
return h;
}

total += judgementCount;
}

return null;
}
Expand Down
12 changes: 12 additions & 0 deletions Quaver.API/Maps/Structures/HitObjectInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ public HitSounds HitSound
set;
}

/// <summary>
/// The hit object could be a normal note or a mine
/// </summary>
public HitObjectType Type { get; [MoonSharpVisible(false)] set; }

/// <summary>
/// Key sounds to play when this object is hit.
/// </summary>
Expand Down Expand Up @@ -95,6 +100,11 @@ public string TimingGroup
[YamlIgnore]
public bool IsLongNote => EndTime > 0;

/// <summary>
/// The number of judgements generated by this object
/// </summary>
[YamlIgnore] public int JudgementCount => IsLongNote && Type != HitObjectType.Mine ? 2 : 1;

/// <summary>
/// Returns if the object is allowed to be edited in lua scripts
/// </summary>
Expand Down Expand Up @@ -175,6 +185,7 @@ public bool Equals(HitObjectInfo x, HitObjectInfo y)
x.Lane == y.Lane &&
x.EndTime == y.EndTime &&
x.HitSound == y.HitSound &&
x.Type == y.Type &&
x.KeySounds.SequenceEqual(y.KeySounds, KeySoundInfo.ByValueComparer) &&
x.EditorLayer == y.EditorLayer;
}
Expand All @@ -186,6 +197,7 @@ public int GetHashCode(HitObjectInfo obj)
var hashCode = obj.StartTime;
hashCode = (hashCode * 397) ^ obj.Lane;
hashCode = (hashCode * 397) ^ obj.EndTime;
hashCode = (hashCode * 397) ^ (int)obj.Type;
hashCode = (hashCode * 397) ^ (int)obj.HitSound;

foreach (var keySound in obj.KeySounds)
Expand Down
3 changes: 3 additions & 0 deletions Quaver.API/Replays/Replay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ public static Replay GeneratePerfectReplayKeys(Replay replay, Qua map)

foreach (var hitObject in map.HitObjects)
{
if (hitObject.Type is HitObjectType.Mine)
continue;

// Add key press frame
nonCombined.Add(new ReplayAutoplayFrame(hitObject, ReplayAutoplayFrameType.Press, hitObject.StartTime, KeyLaneToPressState(hitObject.Lane)));

Expand Down
Loading
Loading