public void Run(IScorePluginArgs args) { var score = args.GetCurrentScore(); var range = args.GetSelectedRange(); int startTick = range.Duration < 0 ? range.StartTick + range.Duration : range.StartTick; int endTick = range.Duration < 0 ? range.StartTick : range.StartTick + range.Duration; var endStepDic = score.Notes.Slides.ToDictionary(p => p, p => p.StepNotes.OrderByDescending(q => q.TickOffset).First()); var airStepDic = score.Notes.Airs .Where(p => endStepDic.Values.Contains(p.ParentNote)) .ToDictionary(p => p.ParentNote as Slide.StepTap, p => p); var airActionStepDic = score.Notes.AirActions .Where(p => endStepDic.Values.Contains(p.ParentNote)) .ToDictionary(p => p.ParentNote as Slide.StepTap, p => p); var targets = score.Notes.Slides .Where(p => p.StartTick >= startTick && p.StartTick + p.GetDuration() <= endTick) .Where(p => p.StartLaneIndex >= range.StartLaneIndex && p.StartLaneIndex + p.StartWidth <= range.StartLaneIndex + range.SelectedLanesCount) .Where(p => p.StepNotes.All(q => q.LaneIndex >= range.StartLaneIndex && q.LaneIndex + q.Width <= range.StartLaneIndex + range.SelectedLanesCount)) .Where(p => !airStepDic.ContainsKey(endStepDic[p]) && !airActionStepDic.ContainsKey(endStepDic[p])) .ToList(); if (targets.Count == 0) { return; } var results = targets.Select(p => { var ordered = p.StepNotes.OrderByDescending(q => q.TickOffset).ToList(); var res = new Slide() { StartTick = startTick + (endTick - ordered[0].Tick) }; res.SetPosition(ordered[0].LaneIndex, ordered[0].Width); var trailing = new Slide.StepTap(res) { IsVisible = true, TickOffset = startTick + (endTick - p.StartTick) - res.StartTick }; trailing.SetPosition(p.StartLaneIndex - res.StartLaneIndex, p.StartWidth - res.StartWidth); var steps = ordered.Skip(1).Select(q => { var step = new Slide.StepTap(res) { IsVisible = q.IsVisible, TickOffset = startTick + (endTick - q.Tick) - res.StartTick }; step.SetPosition(q.LaneIndex - res.StartLaneIndex, q.Width - res.StartWidth); return(step); }) .Concat(new[] { trailing }); res.StepNotes.AddRange(steps); return(res); }); foreach (var slide in targets) { score.Notes.Slides.Remove(slide); } score.Notes.Slides.AddRange(results); args.UpdateScore(score); }
public void Run(IScorePluginArgs args) { var form = new ShiftTimeSelectionForm(); if (form.ShowDialog() != DialogResult.OK) { return; } if (form.CountValue == 0) { return; } var score = args.GetCurrentScore(); int origin = args.GetSelectedRange().StartTick; BarIndexCalculator barIndexCalculator; try { barIndexCalculator = new BarIndexCalculator(score.TicksPerBeat, score.Events.TimeSignatureChangeEvents); } catch (InvalidTimeSignatureException ex) { int beatAt = ex.Tick / score.TicksPerBeat + 1; MessageBox.Show(string.Format(ErrorStrings.InvalidTimeSignature, beatAt), DisplayName, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } var barIndex = barIndexCalculator.GetBarPositionFromTick(origin).BarIndex; var sig = barIndexCalculator.GetTimeSignatureFromBarIndex(barIndex); int offset = 4 * score.TicksPerBeat * form.CountValue * (form.DurationType == DurationType.Bar ? sig.Numerator : 1) / sig.Denominator; var(heading, targets) = Partition(score.Events.AllEvents.Where(p => p.Tick > 0), p => p.Tick <= origin); if (targets.Count == 0) { return; } int firstEventTick = targets.Min(p => p.Tick); int lowerLimitTick = heading.Count == 0 ? 0 : heading.Max(p => p.Tick); if (offset < 0 && firstEventTick + offset <= lowerLimitTick) { MessageBox.Show("移動対象のイベントが先行するイベントを追い越すため、移動は実行されません。", DisplayName, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } foreach (var item in targets) { item.Tick += offset; } args.UpdateScore(score); }
public void Run(IScorePluginArgs args) { var score = args.GetCurrentScore(); var range = args.GetSelectedRange(); var slides = score.Notes.Slides .Where(p => p.StartTick <= range.StartTick && p.StepNotes.OrderByDescending(q => q.Tick).First().Tick >= range.StartTick); foreach (var slide in slides.Where(p => p.StepNotes.Count == 3)) { var steps = slide.StepNotes.OrderBy(p => p.TickOffset).ToList(); // 始点と2つ目の中継点間の時間が等しいものが対象 int initInterval = steps[0].TickOffset; if (initInterval * 2 != steps[1].TickOffset) { continue; } bool stepVisible = steps[0].IsVisible; int duration = steps[steps.Count - 1].TickOffset; int stepsCount = duration / initInterval; for (int i = 0; i < stepsCount - 2; i++) { int pos = initInterval * (i + 3); if (pos >= duration) { break; } var step = new Core.Notes.Slide.StepTap(slide) { TickOffset = pos, IsVisible = stepVisible }; step.SetPosition(steps[i % 2].LaneIndexOffset, steps[i % 2].WidthChange); slide.StepNotes.Add(step); } } args.UpdateScore(score); }
public void Run(IScorePluginArgs args) { var score = args.GetCurrentScore(); var range = args.GetSelectedRange(); bool modified = false; var targets = score.Notes.Slides.Where(p => p.StartTick <range.StartTick && p.StepNotes.OrderByDescending(q => q.TickOffset).First().Tick> range.StartTick); var endStepDic = score.Notes.Slides.ToDictionary(p => p, p => p.StepNotes.OrderByDescending(q => q.TickOffset).First()); var airStepDic = score.Notes.Airs .Where(p => endStepDic.Values.Contains(p.ParentNote)) .ToDictionary(p => p.ParentNote as Slide.StepTap, p => p); var airActionStepDic = score.Notes.AirActions .Where(p => endStepDic.Values.Contains(p.ParentNote)) .ToDictionary(p => p.ParentNote as Slide.StepTap, p => p); foreach (var slide in targets.ToList()) { // カーソル位置に中継点が存在しなければ処理しない int offset = range.StartTick - slide.StartTick; if (slide.StepNotes.All(p => p.TickOffset != offset)) { continue; } var first = new Slide() { StartTick = slide.StartTick }; first.SetPosition(slide.StartLaneIndex, slide.StartWidth); first.StepNotes.AddRange(slide.StepNotes.OrderBy(p => p.TickOffset).TakeWhile(p => p.TickOffset <= offset).Select(p => { var step = new Slide.StepTap(first) { TickOffset = p.TickOffset, IsVisible = p.IsVisible }; step.SetPosition(p.LaneIndexOffset, p.WidthChange); return(step); })); first.StepNotes[first.StepNotes.Count - 1].IsVisible = true; var second = new Slide() { StartTick = range.StartTick }; var trailing = slide.StepNotes.OrderBy(p => p.TickOffset).SkipWhile(p => p.TickOffset < offset).ToList(); second.SetPosition(trailing[0].LaneIndex, trailing[0].Width); second.StepNotes.AddRange(trailing.Skip(1).Select(p => { var step = new Slide.StepTap(second) { TickOffset = p.TickOffset - offset, IsVisible = p.IsVisible }; step.SetPosition(p.LaneIndex - second.StartLaneIndex, p.Width - second.StartWidth); return(step); })); // 終点AIRをsecondに挿入 if (airStepDic.ContainsKey(endStepDic[slide])) { var origAir = airStepDic[endStepDic[slide]]; var air = new Air(second.StepNotes[second.StepNotes.Count - 1]) { VerticalDirection = origAir.VerticalDirection, HorizontalDirection = origAir.HorizontalDirection }; score.Notes.Airs.Remove(origAir); score.Notes.Airs.Add(air); } if (airActionStepDic.ContainsKey(endStepDic[slide])) { var origAirAction = airActionStepDic[endStepDic[slide]]; var airAction = new AirAction(second.StepNotes[second.StepNotes.Count - 1]); airAction.ActionNotes.AddRange(origAirAction.ActionNotes.Select(p => new AirAction.ActionNote(airAction) { Offset = p.Offset })); score.Notes.AirActions.Remove(origAirAction); score.Notes.AirActions.Add(airAction); } score.Notes.Slides.Add(first); score.Notes.Slides.Add(second); score.Notes.Slides.Remove(slide); modified = true; } if (modified) { args.UpdateScore(score); } }
public void Run(IScorePluginArgs args) { var score = args.GetCurrentScore(); var range = args.GetSelectedRange(); bool modified = false; int startTick = range.Duration < 0 ? range.StartTick + range.Duration : range.StartTick; int endTick = range.Duration < 0 ? range.StartTick : range.StartTick + range.Duration; var endStepDic = score.Notes.Slides.ToDictionary(p => p, p => p.StepNotes.OrderByDescending(q => q.TickOffset).First()); var airStepDic = score.Notes.Airs .Where(p => endStepDic.Values.Contains(p.ParentNote)) .ToDictionary(p => p.ParentNote as Slide.StepTap, p => p); var airActionStepDic = score.Notes.AirActions .Where(p => endStepDic.Values.Contains(p.ParentNote)) .ToDictionary(p => p.ParentNote as Slide.StepTap, p => p); var startDic = score.Notes.Slides.Where(p => p.StartTick >= startTick && p.StartTick <= endTick) .Select(p => new { Position = Tuple.Create(p.StartTick, p.StartLaneIndex, p.StartWidth), Note = p }) .GroupBy(p => p.Position) .ToDictionary(p => p.Key, p => p.Select(q => q.Note).ToList()); var endDic = score.Notes.Slides.Where(p => endStepDic[p].Tick >= startTick && endStepDic[p].Tick <= endTick) .Select(p => new { Position = Tuple.Create(endStepDic[p].Tick, endStepDic[p].LaneIndex, endStepDic[p].Width), Note = p }) .GroupBy(p => p.Position) .ToDictionary(p => p.Key, p => p.Select(q => q.Note).ToList()); while (endDic.Count > 0) { var pos = endDic.First().Key; if (endDic[pos].Count == 0 || !startDic.ContainsKey(pos) || startDic[pos].Count == 0) { endDic.Remove(pos); continue; } if (startDic[pos].Count > 0) { // 終点AIR付きスライドはheadingの対象外 while (endDic[pos].Count > 0 && (airStepDic.ContainsKey(endStepDic[endDic[pos][0]]) || airActionStepDic.ContainsKey(endStepDic[endDic[pos][0]]))) { endDic[pos].RemoveAt(0); } if (endDic[pos].Count == 0) { endDic.Remove(pos); continue; } var heading = endDic[pos][0]; var trailing = startDic[pos][0]; var trailingOldSteps = trailing.StepNotes.OrderBy(p => p.TickOffset).ToList(); heading.StepNotes.AddRange(trailingOldSteps.Select(p => { var step = new Slide.StepTap(heading) { TickOffset = p.Tick - heading.StartTick, IsVisible = p.IsVisible }; step.SetPosition(p.LaneIndex - heading.StartLaneIndex, p.Width - heading.StartWidth); return(step); })); // trailingにAIRが追加されていれば反映 var trailingOldEndStep = trailingOldSteps[trailingOldSteps.Count - 1]; var trailingNewEndStep = heading.StepNotes[heading.StepNotes.Count - 1]; if (airStepDic.ContainsKey(trailingOldEndStep)) { var air = new Air(trailingNewEndStep) { VerticalDirection = airStepDic[trailingOldEndStep].VerticalDirection, HorizontalDirection = airStepDic[trailingOldEndStep].HorizontalDirection }; score.Notes.Airs.Add(air); score.Notes.Airs.Remove(airStepDic[trailingOldEndStep]); airStepDic.Add(trailingNewEndStep, air); airStepDic.Remove(trailingOldEndStep); } if (airActionStepDic.ContainsKey(trailingOldEndStep)) { var airAction = new AirAction(trailingNewEndStep); airAction.ActionNotes.AddRange(airActionStepDic[trailingOldEndStep].ActionNotes.Select(p => new AirAction.ActionNote(airAction) { Offset = p.Offset })); score.Notes.AirActions.Add(airAction); score.Notes.AirActions.Remove(airActionStepDic[trailingOldEndStep]); airActionStepDic.Add(trailingNewEndStep, airAction); airActionStepDic.Remove(trailingOldEndStep); } endStepDic[heading] = trailingNewEndStep; score.Notes.Slides.Remove(trailing); startDic[pos].Remove(trailing); var trailingEndPos = Tuple.Create(endStepDic[trailing].Tick, endStepDic[trailing].LaneIndex, endStepDic[trailing].Width); if (endDic.ContainsKey(trailingEndPos)) { endDic[trailingEndPos].Remove(trailing); } endDic[pos].Remove(heading); if (!endDic.ContainsKey(trailingEndPos)) { endDic.Add(trailingEndPos, new[] { heading }.ToList()); } else { endDic[trailingEndPos].Add(heading); } modified = true; } } if (modified) { args.UpdateScore(score); } }