Skip to content

Commit

Permalink
Code changes for v0.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Jumprocks1 committed Jun 16, 2024
1 parent 42e4471 commit 82b4892
Show file tree
Hide file tree
Showing 126 changed files with 3,610 additions and 1,103 deletions.
1 change: 1 addition & 0 deletions DrumGame/DrumGame-Game/API/FFmpegProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public void ExtractImage(string outputPath)
AddOutput(outputPath);
}

public void SwapChannels() => AddArguments("-map_channel", "0.0.1", "-map_channel", "0.0.0");
public void SimpleAudio() // removes images
{
AddArgument("-map_metadata");
Expand Down
47 changes: 16 additions & 31 deletions DrumGame/DrumGame-Game/Beatmaps/Beatmap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using Commons.Music.Midi;
using DrumGame.Game.Beatmaps.Data;
using DrumGame.Game.Beatmaps.Formats;
using DrumGame.Game.Beatmaps.Loaders;
using DrumGame.Game.Channels;
using DrumGame.Game.Interfaces;
Expand Down Expand Up @@ -59,26 +60,10 @@ public override double LeadIn
OffsetUpdated?.Invoke();
}
}

double _localOffset;
public double LocalOffset
{
get => _localOffset;
set
{
if (_localOffset == value) return;
_localOffset = value;
using (var context = Util.GetDbContext())
{
var beatmap = context.GetOrAddBeatmap(Id);
beatmap.LocalOffset = value;
context.SaveChanges();
}
FireOffsetUpdated();
}
}
public bool UseYouTubeOffset;
public double TotalOffset => UseYouTubeOffset ? StartOffset + _localOffset + YouTubeOffset : StartOffset + _localOffset;
public double CurrentTrackStartOffset => UseYouTubeOffset ? StartOffset + YouTubeOffset : StartOffset;
public double TotalOffset => CurrentTrackStartOffset;
public string MapStoragePath => Source.MapStoragePath;

public new string Id { get => base.Id ?? Source.FilenameNoExt; set => base.Id = value; }
public double CurrentRelativeVolume => RelativeVolume ?? BJson.DefaultRelativeVolume;
Expand Down Expand Up @@ -130,21 +115,12 @@ public void Init()
HitObjects.Add(new HitObject(TickFromBeat(t), data));
}
}
BeatmapLoader.LoadTempo(this, true);
BeatmapLoader.LoadMeasures(this, true);
BJsonLoadHelpers.LoadTempo(this, true);
BJsonLoadHelpers.LoadMeasures(this, true);
QuarterNotes = Math.Max((int)(t + 1), 4);
// We use OrderBy instead of List.Sort since OrderBy is stable sort
HitObjects = HitObjects.OrderBy(e => e.Time).ToList();
TempoChanges = TempoChanges.OrderBy(e => e.Time).ToList();

if (Util.LoadLocalOffset)
{
// unfortunately this takes ~12ms the first time it runs
// afterwards it usually takes 0.5ms
// in the long run it is probably worth it since we can load all sorts of data from the database
using var context = Util.GetDbContext();
_localOffset = context.Find<Stores.DB.BeatmapInfo>(Id)?.LocalOffset ?? 0;
}
Notes = null;
}

Expand All @@ -163,7 +139,16 @@ public bool TrySetName(string name)
Logger.Log($"Failed to rename beatmap, file already exists at {path}", level: LogLevel.Error);
return false;
}
Source.AbsolutePath = path;
// since we're changing the name and setting the format, we need to remove old format tags
if (Source.Format != null && Source.Format != BJsonFormat.Instance)
{
RemoveTags(Source.Format.MountTag);
AddTags(Source.Format.ConvertTag);
}
Source = new BJsonSource(path, BJsonFormat.Instance)
{
MapStoragePath = Source.MapStoragePath
};
if (Source.MapStoragePath != null)
{
// We have to be careful here. When using libraries, the game uses $library/ as the prefix,
Expand Down
110 changes: 80 additions & 30 deletions DrumGame/DrumGame-Game/Beatmaps/BeatmapExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using DrumGame.Game.Beatmaps.Data;
using DrumGame.Game.Beatmaps.Display;
using DrumGame.Game.Beatmaps.Editor;
using DrumGame.Game.Beatmaps.Formats;
using DrumGame.Game.Beatmaps.Loaders;
using DrumGame.Game.Channels;
using DrumGame.Game.Commands.Requests;
Expand Down Expand Up @@ -179,42 +180,55 @@ public IOrderedEnumerable<double> GetTimelineMarks()
.OrderBy(e => e);
}

public void TrySaveToDisk(MapStorage mapStorage, BeatmapEditor editor = null)
// returns true if the map was synchronously saved
public bool TrySaveToDisk(BeatmapEditor editor = null)
{
if (!Source.BJson)
if (!Source.Format.CanSave)
{
Util.Palette.Push(SaveRequest.DtxSaveRequest(Source.FilenameWithExt, removePrevious =>
Util.Palette.Push(SaveRequest.ConvertSaveRequest(Source, removePrevious =>
{
var library = Source.Library;
var enableBjson = !library.IsMain && !library.ScanBjson;
var oldPath = Source.MapStoragePath;
if (TrySetName(Source.FilenameNoExt))
{
editor?.ForceDirty();
if (removePrevious) mapStorage.Delete(oldPath);
if (removePrevious) Util.MapStorage.Delete(oldPath);
else Id = Guid.NewGuid().ToString();
TrySaveToDisk(mapStorage, editor);
TrySaveToDisk(editor);
if (enableBjson)
{
library.ScanBjson = true;
Util.MapStorage.MapLibraries.InvokeChanged(library);
}
}
}));
return;
return false;
}
try
{
var o = SaveToDisk(mapStorage);
var o = SaveToDisk(Util.MapStorage);
editor?.Display?.LogEvent($"Saved to {o}");
editor?.MarkSaveHistory();
return true;
}
catch (UserException e)
{
Util.Palette.UserError(e);
}
return false;
}

// Make sure to call .Export() before this
public string SaveToDisk(MapStorage mapStorage, MapImportContext context = null)
{
if (DisableSaving)
throw new UserException("Map saving disabled. Likely caused by application of a modifier.");
// if (Notes == null) throw new Exception("Attempted to save a beatmap before it was exported. Please report this issue to the developer.");
var target = Source.AbsolutePath;
if (!Source.BJson) throw new UserException("Can only save .bjson files");
if (!Source.Format.CanSave) throw new UserException("Can only save .bjson files");
using var stream = mapStorage.GetStream(target, FileAccess.Write, FileMode.Create);
using var writer = new StreamWriter(stream);
context ??= MapImportContext.Current;
Expand Down Expand Up @@ -389,12 +403,13 @@ IEnumerable<int> it()
{
var end = TickFromBeat(selection.Right);
var startIndex = HitObjects.BinarySearchFirst(TickFromBeat(selection.Left));
for (int i = startIndex; i < HitObjects.Count; i++)
for (var i = startIndex; i < HitObjects.Count; i++)
{
if (HitObjects[i].Time >= end) break;
yield return i;
}
}
if (selection == null) return Enumerable.Range(0, HitObjects.Count);
return selection.HasVolume ? it() : GetHitObjectsAt(selection.Left);
}
public IEnumerable<int> GetHitObjectsInTicks(int start, int end)
Expand Down Expand Up @@ -776,31 +791,15 @@ public double EndTime()
}

public int NextHit(double beat) => HitObjects.BinarySearchThrough(TickFromBeat(beat));
public void Move(MapStorage mapStorage)
{
var oldAudio = FullAudioPath();
Source = new BJsonSource(Path.Join(mapStorage.AbsolutePath, Path.GetFileName(Source.Filename)));
Audio = "audio/" + Path.GetFileName(Audio);
if (Audio != null)
{
try
{
File.Copy(oldAudio, FullAudioPath());
Logger.Log($"copied audio to {FullAudioPath()}");
}
catch { }
}
SaveToDisk(mapStorage);
}
public void CollapseCrashes()
public void CollapseCrashes(int epsilon = 0)
{
var lastCrash = -1;
for (var i = 0; i < HitObjects.Count; i++)
{
var e = HitObjects[i];
if (e.Channel == DrumChannel.Crash || e.Channel == DrumChannel.China)
{
if (lastCrash != -1 && HitObjects[lastCrash].Time == e.Time)
if (lastCrash != -1 && Math.Abs(HitObjects[lastCrash].Time - e.Time) <= epsilon)
{
HitObjects[lastCrash] = new HitObject(e.Time, new HitObjectData(DrumChannel.Crash, NoteModifiers.Accented));
HitObjects.RemoveAt(i);
Expand Down Expand Up @@ -888,6 +887,53 @@ void EndStreak()
EndStreak();
}

public string Simplify(BeatSelection selection)
{
var remove = new List<int>();
bool RemovePending()
{
if (remove.Count == 0) return false;
for (var i = remove.Count - 1; i >= 0; i--)
HitObjects.RemoveAt(remove[i]);
return true;
}
var hos = GetHitObjectsIn(selection).ToList();
if (hos.Count == 0) return null;
foreach (var i in hos)
{
if (HitObjects[i].Channel == DrumChannel.BassDrum && HitObjects[i].Modifiers.HasFlag(NoteModifiers.Left))
remove.Add(i);
}
if (RemovePending()) return "remove left bass";
foreach (var i in hos)
{
if (HitObjects[i].Modifiers.HasFlag(NoteModifiers.Ghost))
remove.Add(i);
}
if (RemovePending()) return "remove ghost";
var hoDiff = hos
.Select(i =>
{
var ho = HitObjects[i];
var offset = (ho.Time - MeasureStartTickFromTick(ho.Time)) % TickRate;
var gcd = Util.GCD(offset, TickRate);
var diff = TickRate / gcd;
return (i, diff);
})
.ToList();
var hardest = hoDiff.Max(e => e.diff);
if (hardest > 1)
{
foreach (var (i, diff) in hoDiff)
{
if (diff == hardest)
remove.Add(i);
}
}
if (RemovePending()) return $"remove {hardest} snap";
return null;
}

public IEnumerable<(double, bool)> BeatLinesMs()
{
// this only takes like 0.5ms
Expand Down Expand Up @@ -917,10 +963,14 @@ public IEnumerable<(double, bool)> BeatLinesMs()

public void HashId() => Id = MetaHash();
public string MetaHash() => Util.MD5(Title ?? "", Artist ?? "", DifficultyName ?? Difficulty ?? "", Mapper ?? "", Description ?? "", Tags ?? "");
// note, this doesn't work for things like (TV Size) being in the title, oh well
// in those cases, we will have to manually set the map set
public string MapSetHash() => Util.MD5(Title ?? "", Artist ?? "", Mapper ?? "");
public string MapSetIdNonNull => MapSetId ?? MapSetHash();
public void HashImageUrl()
{
var slash = ImageUrl.LastIndexOf("/");
var dot = ImageUrl.LastIndexOf(".");
var slash = ImageUrl.LastIndexOf('/');
var dot = ImageUrl.LastIndexOf('.');
if (slash > dot)
Image = "images/" + Util.MD5(ImageUrl).ToLower();
else
Expand Down Expand Up @@ -983,7 +1033,7 @@ public string BpmRange
if (TempoChanges == null)
{
TickRate = DefaultTickRate;
BeatmapLoader.LoadTempo(this);
BJsonLoadHelpers.LoadTempo(this);
}
if (TempoChanges.Count == 1 && TempoChanges[0].Time == 0 || TempoChanges.Count == 0)
return null;
Expand Down
18 changes: 9 additions & 9 deletions DrumGame/DrumGame-Game/Beatmaps/BeatmapPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class BeatmapPlayer : CompositeDrawable
public CommandController Command => Util.CommandController;
public BeatmapSelectorLoader Loader => Dependencies.Get<BeatmapSelectorLoader>();
protected virtual bool AutoStart => true;
public virtual BeatmapPlayerMode Mode
public BeatmapPlayerMode Mode
{
get => _mode; set
{
Expand Down Expand Up @@ -88,9 +88,12 @@ public virtual BeatmapPlayerMode Mode
var measureLines = (edit && !record) || Util.Skin.Notation.MeasureLines;
if (d.MeasureLines == null == measureLines) d.ToggleMeasureLines();
}
ProtectedModeChanged(value);
ModeChanged?.Invoke(value);
}
}
// added so that ModeChanged is always called after child mode change
protected virtual void ProtectedModeChanged(BeatmapPlayerMode mode) { }
public event Action<BeatmapPlayerMode> ModeChanged;
public readonly Beatmap Beatmap;
public BeatClock Track;
Expand Down Expand Up @@ -291,11 +294,13 @@ protected override void Dispose(bool isDisposing)
Beatmap.LengthChanged -= LengthChanged;
Util.DrumGame.VolumeController.MetronomeVolume.Muted.ValueChanged -= MetronomeMuteChanged;
BeatmapPlayerInputHandler?.Dispose();
PracticeMode?.Exit();
PracticeMode = null;
Command.RemoveHandlers(this);
Track.Dispose();
}
[CommandHandler] public void Next() => Track.SeekToBeat(Track.NextHitOrBeat(true));
[CommandHandler] public void Previous() => Track.SeekToBeat(Track.NextHitOrBeat(false));
[CommandHandler] public void NextNote() => Track.SeekToBeat(Track.NextHitOrBeat(true));
[CommandHandler] public void PreviousNote() => Track.SeekToBeat(Track.NextHitOrBeat(false));
[CommandHandler]
public void SwitchMode()
{
Expand Down Expand Up @@ -365,7 +370,7 @@ public bool AddAudio(string file)
if (ed == null)
{
Beatmap.Export();
Beatmap.TrySaveToDisk(MapStorage);
Beatmap.TrySaveToDisk();
}
else
{
Expand Down Expand Up @@ -553,11 +558,6 @@ protected override bool OnKeyDown(KeyDownEvent e)


[CommandHandler] public void RevealAudioInFileExplorer() => Util.RevealInFileExplorer(CurrentAudioPath);

[CommandHandler]
public bool SetLocalOffset(CommandContext context) =>
context.Palette.RequestNumber("Setting Local Offset", "Local offset", Beatmap.LocalOffset,
e => Beatmap.LocalOffset = e);
Metronome _metronome;
void MetronomeMuteChanged(ValueChangedEvent<bool> e)
{
Expand Down
7 changes: 5 additions & 2 deletions DrumGame/DrumGame-Game/Beatmaps/Display/BeatmapDisplay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ public abstract class BeatmapDisplay : CompositeDrawable
public abstract void PullView(ViewTarget viewTarget);
public abstract void OnDrumTrigger(DrumChannelEvent ev);

// used with JudgementHiderModifier
public bool HideJudgements = false;

protected BeatmapPlayerInputHandler InputHandler => Player.BeatmapPlayerInputHandler;
public BeatmapScorer Scorer => InputHandler.Scorer;

HitErrorDisplay HitErrorDisplay;
public HitErrorDisplay HitErrorDisplay;
public virtual void EnterPlayMode() // TODO should really just swap this with a mode change listener
{
AddInternal(HitErrorDisplay = new HitErrorDisplay(this, BeatmapScorer.HitWindows));
Expand Down Expand Up @@ -53,5 +56,5 @@ protected override void Dispose(bool isDisposing)
}
public PracticeInfoPanel PracticeInfoPanel;
public abstract PracticeInfoPanel StartPractice(PracticeMode practice);
public abstract void EndPractice(PracticeMode practice);
public abstract void ExitPractice(PracticeMode practice);
}
Loading

0 comments on commit 82b4892

Please sign in to comment.