public override void Apply(double time, S2VXStory story) { var bpm = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.BPM = bpm; story.Offset = StartTime; }
public static Result Merge(string[] inputs, string output) { var validateResult = ParameterValidator.Validate(inputs, output); if (!validateResult.IsSuccessful) { return(validateResult); } var(loadResult, loadedStories) = InputsLoader.Load(inputs); if (!loadResult.IsSuccessful) { return(validateResult); } var outputStory = new S2VXStory(); var notesResult = NotesMerger.Merge(loadedStories, outputStory); var commandsResult = CommandsMerger.Merge(loadedStories, outputStory); outputStory.Save(output); var messages = new[] { $"Merged {inputs.Length} stories into \"{output}\"", notesResult.Message, commandsResult.Message }; var message = string.Join("\n\n", messages); return(new Result { IsSuccessful = true, Message = message }); }
public static (Result result, List <S2VXStory> loadedStories) Load(string[] inputs) { var loadedStories = new List <S2VXStory>(); foreach (var input in inputs) { var story = new S2VXStory(); try { story.Open(input, true); } catch (Exception e) { return( new Result { IsSuccessful = false, Message = $"Input file failed to load: \"{input}\"\n{e.Message}" }, loadedStories ); } loadedStories.Add(story); } return(new Result { IsSuccessful = true }, loadedStories); }
public override void Apply(double time, S2VXStory story) { var position = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.Camera.TakeCameraPositionLock(this); story.Camera.SetPosition(this, position); story.Camera.ReleaseCameraPositionLock(this); }
public override void Apply(double time, S2VXStory story) { var scale = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.Camera.TakeCameraScaleLock(this); story.Camera.SetScale(this, scale); story.Camera.ReleaseCameraScaleLock(this); }
public void SetUp() { var(_, loadedStories) = InputsLoader.Load(new[] { "Samples/NotesAlphaFrom0To0.s2ry", "Samples/NotesAlphaFrom0To1000.s2ry", }); OutputStory = new S2VXStory(); Result = CommandsMerger.Merge(loadedStories, OutputStory); }
public void SetUp() { var(_, loadedStories) = InputsLoader.Load(new[] { "Samples/HoldNoteFrom0To1000.s2ry", "Samples/HoldNoteFrom500To1500.s2ry", }); OutputStory = new S2VXStory(); Result = NotesMerger.Merge(loadedStories, OutputStory); }
/// <summary> /// Note that conflicts will be reported for any notes that share the /// same start/end times. This is to prevent a player from trying to /// play multiple notes at one time. /// /// Example time ranges that are not conflicts: /// (0-0, 500-500, 1000-1000) /// (0-0, 500-1000) /// /// Example time ranges that are conflicts: /// (0-0, 0-0) /// (0-0, 0-1000) /// (0-1000, 500-1500) /// </summary> public static Result Merge(IEnumerable <S2VXStory> inputStories, S2VXStory outputStory) { var infos = new List <NoteTimeInfo>(); foreach (var input in inputStories) { foreach (var note in input.Notes.GetNonHoldNotes()) { outputStory.AddNote(CopyNote(note)); infos.Add(new NoteTimeInfo(note)); } foreach (var holdNote in input.Notes.GetHoldNotes()) { outputStory.AddNote(CopyHoldNote(holdNote)); infos.Add(new NoteTimeInfo(holdNote)); } } infos.Sort(); var messages = new List <string>(); NoteTimeInfo latestInfo = null; foreach (var info in infos) { if (latestInfo == null) { latestInfo = info; continue; } if (info.StartTime > latestInfo.EndTime && info.EndTime > latestInfo.EndTime) { latestInfo = info; } else { messages.Add($"Note conflict:\n{latestInfo}\n{info}"); if (info.EndTime > latestInfo.EndTime) { latestInfo = info; } } } if (messages.Count == 0) { messages.Add("No note conflicts found"); } return(new Result { IsSuccessful = true, Message = string.Join("\n\n", messages) }); }
private void LoadPlay() { try { var story = new S2VXStory(StoryPath, false); var track = S2VXTrack.Open(AudioPath, Audio); Screens.Push(new PlayScreen(false, story, track)); } catch (Exception exception) { BtnPlay.BorderThickness = 5; Console.WriteLine(exception); } }
/// <summary> /// Note that different from notes, commands can share time boundaries. /// For example, (0-0, 0-1000) is valid. However, duplicate commands, /// e.g. (0-0, 0-0) are not allowed. /// /// Example time ranges that are not conflicts: /// (0-0, 500-500, 1000-1000) /// (0-0, 500-1000) /// (0-0, 0-1000) /// /// Example time ranges that are conflicts: /// (0-0, 0-0) /// (0-1000, 500-1500) /// </summary> public static Result Merge(IEnumerable <S2VXStory> inputStories, S2VXStory outputStory) { var infos = new List <CommandTimeInfo>(); foreach (var input in inputStories) { foreach (var command in input.Commands) { outputStory.AddCommand(command); infos.Add(new CommandTimeInfo(command)); } } infos.Sort(); var messages = new List <string>(); var dictInfo = new Dictionary <string, CommandTimeInfo>(); foreach (var info in infos) { var type = info.Type; if (!dictInfo.TryGetValue(type, out var latestInfo)) { dictInfo[type] = info; continue; } if (info.StartTime == latestInfo.StartTime && info.EndTime == latestInfo.EndTime) { messages.Add($"Command conflict:\n{latestInfo}\n{info}"); } else if (info.StartTime >= latestInfo.EndTime && info.EndTime >= latestInfo.EndTime) { dictInfo[type] = info; } else { messages.Add($"Command conflict:\n{latestInfo}\n{info}"); if (info.EndTime > latestInfo.EndTime) { dictInfo[type] = info; } } } if (messages.Count == 0) { messages.Add("No command conflicts found"); } return(new Result { IsSuccessful = true, Message = string.Join("\n\n", messages) }); }
private void Load(AudioManager audio) { var storyPath = Path.Combine("VisualTests", "EditorScreenTests", "ValidStory.s2ry"); Story = new S2VXStory(); Story.Open(storyPath, true); var audioPath = Path.Combine("TestTracks", "10-seconds-of-silence.mp3"); Track = S2VXTrack.Open(audioPath, audio); Add(new ScreenStack(Editor = new EditorScreen(Story, Track))); }
// Updates properties based on story configuration public void Calculate(S2VXStory story) { var commands = story.Commands; CommandCount = commands.Count; var timingCommands = story.Commands.OfType <TimingChangeCommand>(); if (timingCommands.Any()) { SlowestBPM = timingCommands.Min(t => Math.Min(t.StartValue, t.EndValue)); FastestBPM = timingCommands.Max(t => Math.Max(t.StartValue, t.EndValue)); } var notes = story.Notes.Children; NoteCount = notes.Count; if (NoteCount > 0) { var min = notes.Min(n => n.HitTime); var max = notes.Max(n => n.HitTime); StoryLength = max - min; } }
public void SetUp() { var story = new S2VXStory(); var holdNote = new EditorHoldNote { HitTime = 100, EndTime = 400, Coordinates = new(1, 1), EndCoordinates = new(4, 4), }; holdNote.MidCoordinates.Add(new(2, 2)); holdNote.MidCoordinates.Add(new(3, 3)); story.AddNote(holdNote); var filePath = "HoldNoteLoadingTests_Open_HoldNote_SetUp.s2ry"; story.Save(filePath); var newStory = new S2VXStory(); newStory.Open(filePath, true); LoadedHoldNote = newStory.Notes.GetHoldNotes().First(); }
public abstract void Apply(double time, S2VXStory story);
public override void Apply(double time, S2VXStory story) { var showTime = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.Notes.ShowTime = showTime; }
public override void Apply(double time, S2VXStory story) { var value = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.Notes.NoteOutlineColor = value; }
public override void ReversibleRemove(S2VXStory story, EditorScreen editor) => editor.Reversibles.Push(new ReversibleRemoveHoldNote(story, this, editor));
public ReversibleRemoveNote(S2VXStory story, S2VXNote note, EditorScreen editor) { Story = story; Note = note; Editor = editor; }
public ReversibleAddHoldNote(S2VXStory story, HoldNote note, EditorScreen editor) { Story = story; Note = note; Editor = editor; }
private void Load() { var width = Width; var songInfoHeight = width * 0.4f; var leaderboardWidth = width * 0.6f; var leaderboardHeight = width * 0.4f; var btnHeight = width * 0.2f; var spacingMargin = 0.05f; var textSize = SizeConsts.TextSize1; var thumbnailSize = width * 0.3f; var btnSize = new Vector2(width / 5, width / 10); BtnEdit = new() { Origin = Anchor.Centre, Anchor = Anchor.Centre, Size = btnSize, Icon = FontAwesome.Solid.Edit, BorderColour = Color4.Red, Masking = true, Action = LoadEditor }; BtnPlay = new() { Origin = Anchor.Centre, Anchor = Anchor.Centre, Size = btnSize, Icon = FontAwesome.Solid.Play, BorderColour = Color4.Red, Masking = true, Action = LoadPlay }; InternalChildren = new Drawable[] { // TODO: add blurred background new FillFlowContainer { Width = width, Height = songInfoHeight, Children = new Drawable[] { // Thumbnail new IconButton { Size = new Vector2(thumbnailSize), Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft, Margin = new MarginPadding { Horizontal = width * spacingMargin, Vertical = width * spacingMargin, }, Texture = ThumbnailTexture, TextureName = "logo", }, TextContainer = new TextFlowContainer(s => s.Font = new FontUsage("default", textSize)) { Width = width - thumbnailSize - width * spacingMargin * 2, Height = songInfoHeight, Margin = new MarginPadding { Vertical = width * spacingMargin, }, TextAnchor = Anchor.TopLeft, Colour = Color4.White, // TODO: truncate text if it's too long }, } }, LeaderboardContainer = new LeaderboardContainer(StoryDirectory) { Width = leaderboardWidth, Height = leaderboardHeight, Y = songInfoHeight, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, }, new FillFlowContainer { Width = width, Height = btnHeight, Y = songInfoHeight + leaderboardHeight, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Direction = FillDirection.Horizontal, Children = new[] { BtnEdit, BtnPlay, } } }; LoadSongMetadata(); } private void LoadEditor() { try { var story = new S2VXStory(StoryPath, true); var track = S2VXTrack.Open(AudioPath, Audio); Screens.Push(new EditorScreen(story, track)); } catch (Exception exception) { BtnEdit.BorderThickness = 5; Console.WriteLine(exception); } }
public override void Apply(double time, S2VXStory story) { var value = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.Approaches.HoldApproachColor = value; }
public override void Apply(double time, S2VXStory story) { var color = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.Background.Colour = color; }
public override void Apply(double time, S2VXStory story) { var alpha = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.Grid.Alpha = alpha; }
public override void Apply(double time, S2VXStory story) { var distance = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.Approaches.Distance = distance; }
public override void Apply(double time, S2VXStory story) { var thickness = S2VXUtils.ClampedInterpolation(time, StartValue, EndValue, StartTime, EndTime, Easing); story.Approaches.Thickness = thickness; }