/// <summary> /// Constructs and adds a note to a pattern. /// </summary> /// <param name="pattern">The pattern to add to.</param> /// <param name="column">The column to add the note to.</param> /// <param name="holdNote">Whether to add a hold note.</param> private void addToPattern(Pattern pattern, int column, bool holdNote) { ManiaHitObject newObject; if (holdNote) { newObject = new HoldNote { StartTime = HitObject.StartTime, Duration = endTime - HitObject.StartTime, Column = column, Samples = HitObject.Samples, NodeSamples = (HitObject as IHasRepeats)?.NodeSamples }; } else { newObject = new Note { StartTime = HitObject.StartTime, Samples = HitObject.Samples, Column = column }; } pattern.Add(newObject); }
/// <summary> /// Constructs and adds a note to a pattern. /// </summary> /// <param name="pattern">The pattern to add to.</param> /// <param name="column">The column to add the note to.</param> /// <param name="startTime">The start time of the note.</param> /// <param name="endTime">The end time of the note (set to <paramref name="startTime"/> for a non-hold note).</param> private void addToPattern(Pattern pattern, int column, double startTime, double endTime) { ManiaHitObject newObject; if (startTime == endTime) { newObject = new Note { StartTime = startTime, Samples = sampleInfoListAt(startTime), Column = column }; } else { var holdNote = new HoldNote { StartTime = startTime, Column = column, Duration = endTime - startTime, Head = { Samples = sampleInfoListAt(startTime) }, Tail = { Samples = sampleInfoListAt(endTime) } }; newObject = holdNote; } pattern.Add(newObject); }
/// <summary> /// Constructs and adds a note to a pattern. /// </summary> /// <param name="pattern">The pattern to add to.</param> /// <param name="column">The column to add the note to.</param> /// <param name="holdNote">Whether to add a hold note.</param> private void addToPattern(Pattern pattern, int column, bool holdNote) { ManiaHitObject newObject; if (holdNote) { var hold = new HoldNote { StartTime = HitObject.StartTime, Column = column, Duration = endTime - HitObject.StartTime }; hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL }); hold.Tail.Samples = HitObject.Samples; newObject = hold; } else { newObject = new Note { StartTime = HitObject.StartTime, Samples = HitObject.Samples, Column = column }; } pattern.Add(newObject); }
public void CalculateTimeOfAllNotes() { foreach (Note n in notes) { n.time = PulseToTime(n.pulse); if (n is HoldNote) { HoldNote h = n as HoldNote; h.endTime = PulseToTime(h.pulse + h.duration); if (Ruleset.instance != null) { h.gracePeriodStart = h.endTime - Ruleset.instance.longNoteGracePeriod; } } if (n is DragNote) { DragNote d = n as DragNote; d.endTime = PulseToTime(d.pulse + d.Duration()); if (Ruleset.instance != null) { d.gracePeriodStart = d.endTime - Ruleset.instance.longNoteGracePeriod; } } } }
public void Initialize(Scan scanRef, Scanline scanlineRef, HoldNote holdNote) { this.scanlineRef = scanlineRef; noteType = holdNote.type; float startX = GetComponent <RectTransform>() .anchoredPosition.x; float endX = scanRef.FloatPulseToXPosition( holdNote.pulse + holdNote.duration, positionEndOfScanOutOfBounds: false, positionAfterScanOutOfBounds: true); trailExtendsLeft = endX < startX; durationTrailInitialWidth = Mathf.Abs(startX - endX); durationTrail.sizeDelta = new Vector2( durationTrailInitialWidth, durationTrail.sizeDelta.y); if (trailExtendsLeft) { durationTrail.localRotation = Quaternion.Euler(0f, 0f, 180f); if (ongoingTrail != null) { ongoingTrail.localRotation = Quaternion.Euler(0f, 0f, 180f); } } if (ongoingTrail != null) { ongoingTrail.sizeDelta = new Vector2(0f, ongoingTrail.sizeDelta.y); } }
public void InitializeTrail() { holdExtensions = new List <HoldExtension>(); HoldNote holdNote = GetComponent <NoteObject>().note as HoldNote; GetComponent <HoldTrailManager>().Initialize( scanRef, scanlineRef, holdNote); }
public void ReturnHoldNoteToPool(HoldNote obj) //音符对象回到对象池 { if (obj != null) { holdNotePool.Push(obj); obj.enabled = false; obj.gameObject.SetActive(false); } }
protected override DrawableManiaHitObject CreateHitObject() { var note = new HoldNote { Duration = 1000 }; note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); return(new DrawableHoldNote(note)); }
private void createHoldNote() { for (int i = 0; i < columns.Count; i++) { var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 }; obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); columns[i].Add(new DrawableHoldNote(obj, columns[i].Action)); } }
private static HoldNote CopyHoldNote(HoldNote holdNote) { var newNote = new EditorHoldNote { HitTime = holdNote.HitTime, EndTime = holdNote.EndTime, Coordinates = holdNote.Coordinates, EndCoordinates = holdNote.EndCoordinates, }; newNote.MidCoordinates.AddRange(holdNote.MidCoordinates); return(newNote); }
private void parseState(double offset, string keys, List <RhythmEvent> notes, BpmGraph bpm) { int totalActions = keys.Count(key => "124LF".Contains(key + "")) + _activeHoldCount; int laneWidth = 32 / keys.Length; for (int i = 0; i < keys.Length; i++) { switch (keys[i]) { case '0': //none break; case '1': //normal notes.Add(new SimpleNote(bpm.FromBeat(offset), new LanePosition(i * laneWidth, laneWidth), totalActions >= 2)); break; case 'M': //mine notes.Add(new Mine(bpm.FromBeat(offset), new LanePosition(i * laneWidth, laneWidth))); break; case 'F': //fake //notes.Add(new Mine(bpm.FromBeat(offset), new LanePosition(i * laneWidth, laneWidth), true)); break; case '2': //start hold case '4': //start roll { notes.Add(new SimpleNote(bpm.FromBeat(offset), new LanePosition(i * laneWidth, laneWidth), keys[i] == '4')); var hold = new HoldNote(bpm.FromBeat(offset), new LanePosition(i * laneWidth, laneWidth), new SlidePoint[1]); notes.Add(hold); _activeHoldCount++; _activeHolds[i * laneWidth] = hold; } break; case '3': // end hold/roll { var activeHold = _activeHolds[i * laneWidth]; activeHold.SlidePoints[0] = new SlidePoint(activeHold, bpm.FromBeat(offset), activeHold.Position); _activeHolds[i * laneWidth] = null; _activeHoldCount--; } break; //TODO holds, rolls, lifts, fakes etc. } } }
//-------------------------Hold音符对象池方法-------------------------- private void CheckSpawnNextHoldNote() //不断检测是否生成下一个新音符 { int currentTime = DelayedSampleTime; int curNum = 1; while (curNum <= initHoldNotesDatas.Count && initHoldNotesDatas.Peek().dTime0 <= currentTime) { holdNoteInitData tempData = initHoldNotesDatas.Dequeue(); // Debug.Log("TimeToGo!"); HoldNote newObj = GetFreshHoldNote(); newObj.Initialized(this, tempData.ID, tempData.sPosition, tempData.tPosition, tempData.direction, tempData.nTime0, tempData.dTime0, tempData.nTime1, tempData.dTime1); curNum++; } }
public void UnpackAllNotes() { notes = new SortedSet <Note>(new NoteComparer()); foreach (string s in packedNotes) { notes.Add(Note.Unpack(s)); } foreach (string s in packedHoldNotes) { notes.Add(HoldNote.Unpack(s)); } foreach (PackedDragNote n in packedDragNotes) { notes.Add(DragNote.Unpack(n)); } }
public Note Clone() { // If performance is necessary, then do it type-by-type and // field-by-field, as in NoteV1.Clone. if (this is HoldNote) { return(HoldNote.Unpack(Pack())); } else if (this is DragNote) { return(DragNote.Unpack((this as DragNote).Pack())); } else { return(Note.Unpack(Pack())); } }
protected override DrawableHitObject <StraightHitObject> GetVisualRepresentation(StraightHitObject h) { Pitch pitch = PlayField.Columns[h.Column].Pitch; Note note = h as Note; HoldNote holdNote = h as HoldNote; string noteName = "Note" + h.StartBar; if (note != null) { return(New <DrawableNote>(new object[] { note, pitch }, noteName)); } if (holdNote != null) { return(null);//New<DrawableHoldNote>(new object[] { note, pitch }, noteName); } return(null); }
public TestSceneHoldNoteSelectionBlueprint() : base(4) { for (int i = 0; i < 4; i++) { var holdNote = new HoldNote { Column = i, StartTime = i * 100, Duration = 500 }; holdNote.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); var drawableHitObject = new DrawableHoldNote(holdNote); Playfield.Add(drawableHitObject); AddBlueprint(new HoldNoteSelectionBlueprint(holdNote), drawableHitObject); } }
private Drawable createHoldNoteDisplay(ScrollingDirection direction) { var note = new HoldNote { StartTime = 999999999, Duration = 1000 }; note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); return(new ScrollingTestContainer(direction) { AutoSizeAxes = Axes.Both, Child = new NoteContainer(direction, $"hold note, scrolling {direction.ToString().ToLower()}") { Child = new DrawableHoldNote(note, ManiaAction.Key1) { RelativeSizeAxes = Axes.Both, AccentColour = Color4.OrangeRed, } } }); }
public TestSceneHoldNoteSelectionBlueprint() { var holdNote = new HoldNote { Column = 0, Duration = 1000 }; holdNote.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); base.Content.Child = content = new ScrollingTestContainer(ScrollingDirection.Down) { Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Y, Width = 50, Child = drawableObject = new DrawableHoldNote(holdNote) { Height = 300, AccentColour = OsuColour.Gray(0.3f) } }; }
private Drawable createHoldNoteDisplay(ScrollingDirection direction, int identifier, out DrawableHoldNote hitObject) { var note = new HoldNote { StartTime = 0, Duration = 5000 }; note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); return(new ScrollingTestContainer(direction) { AutoSizeAxes = Axes.Both, Child = new NoteContainer(direction, $"hold note {identifier}, scrolling {direction.ToString().ToLowerInvariant()}") { Child = hitObject = new DrawableHoldNote(note) { RelativeSizeAxes = Axes.Both, AccentColour = { Value = Color4.OrangeRed }, } } }); }
public HoldExtension SpawnHoldExtension(GameObject prefab, HoldNote n) { GameObject o = Instantiate(prefab, transform); float x = OutOfBoundXPositionBeforeScan(); float y = scanHeight - (n.lane + 0.5f) * laneHeight; RectTransform rect = o.GetComponent <RectTransform>(); rect.pivot = new Vector2(0.5f, 0.5f); rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.zero; rect.anchoredPosition = new Vector2(x, y); rect.sizeDelta = new Vector2(laneHeight, laneHeight); HoldExtension extension = o.GetComponent <HoldExtension>(); holdExtensions.Add(extension); extension.Initialize(this, scanline, n); return(extension); }
public void TestHoldNoteHeadVisibility() { DrawableHoldNote note = null; AddStep("Add hold note", () => { var h = new HoldNote { StartTime = 0, Duration = 1000 }; h.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); column.Add(note = new DrawableHoldNote(h)); }); AddStep("Hold key", () => { clock.CurrentTime = 0; note.OnPressed(new KeyBindingPressEvent <ManiaAction>(GetContainingInputManager().CurrentState, ManiaAction.Key1)); }); AddStep("progress time", () => clock.CurrentTime = 500); AddAssert("head is visible", () => note.Head.Alpha == 1); }
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 TestCaseManiaHitObjects() { Note note1 = new Note(); Note note2 = new Note(); HoldNote holdNote = new HoldNote { StartTime = 1000 }; note1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); note2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); holdNote.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Y, Direction = FillDirection.Horizontal, Spacing = new Vector2(10, 0), // Imagine that the containers containing the drawable notes are the "columns" Children = new Drawable[] { new Container { Name = "Normal note column", Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Y, Width = 50, Children = new[] { new Container { Name = "Timing section", RelativeSizeAxes = Axes.Both, RelativeChildSize = new Vector2(1, 10000), Children = new[] { new DrawableNote(note1, ManiaAction.Key1) { Y = 5000, LifetimeStart = double.MinValue, LifetimeEnd = double.MaxValue, AccentColour = Color4.Red }, new DrawableNote(note2, ManiaAction.Key1) { Y = 6000, LifetimeStart = double.MinValue, LifetimeEnd = double.MaxValue, AccentColour = Color4.Red } } } } }, new Container { Name = "Hold note column", Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Y, Width = 50, Children = new[] { new Container { Name = "Timing section", RelativeSizeAxes = Axes.Both, RelativeChildSize = new Vector2(1, 10000), Children = new[] { new DrawableHoldNote(holdNote, ManiaAction.Key1) { Y = 5000, Height = 1000, LifetimeStart = double.MinValue, LifetimeEnd = double.MaxValue, AccentColour = Color4.Red, } } } } } } }); }
private readonly Regex _arrow = CompileRule("mmm5x: notes"); //Hex bar, B36 startLane, notes public Song ParseSong(string filename) { var theSourceFile = new FileInfo(filename); var reader = theSourceFile.OpenText(); var data = new List <string>(); while (true) { string line = reader.ReadLine(); if (line == null) { break; } if (line.StartsWith("#")) { data.Add(line.Substring(1)); } } bool[] hasBeenRead = new bool[data.Count]; int ticksPerBeat = 480; //default int beatsPerBar = 4; //default TODO this is being ignored! should be slowing down approach rate/effective BPM when increased int barOffset = 0; //default Song song = new Song(); var barSections = new List <BarSection>(); var bpmDefinitions = new Dictionary <int, double>();//BPM ID -> BPM value string difficulty = null; //PASS 1: construct base rhythm model for (int i = 0; i < data.Count; i++) { if (hasBeenRead[i]) { continue; } var line = data[i]; //assume we read this line (simplifies our code a bit) hasBeenRead[i] = true; //now try all regex rules for this stage in sequence: var match = _barLength.Match(line); if (match.Success) { barSections.Add(new BarSection(ParseMmm(match.Groups[1]), ParseInt(match.Groups[2]))); continue; } match = _bpmDef.Match(line); if (match.Success) { bpmDefinitions.Add(ParseZz(match.Groups[1]), ParseDouble(match.Groups[2])); continue; } //also parse song info while we're at it: match = _wave.Match(line); if (match.Success) { song.AudioFile = match.Groups[1].Value; continue; } match = _waveOffset.Match(line); if (match.Success) { song.Offset = ParseDouble(match.Groups[1]); continue; } //reach here, nothing matched, so we didn't read this line after all hasBeenRead[i] = false; } //We now have enough information to construct the Bar->Beat converter var barToBeat = BpmGraph.ParseBars(barSections); var bpmChanges = new List <BeatEvent>(); //PASS 2: construct internal rhythm model for (int i = 0; i < data.Count; i++) { if (hasBeenRead[i]) { continue; } var line = data[i]; //assume we read this line (simplifies our code a bit) hasBeenRead[i] = true; //now try all regex rules for this stage in sequence: var match = _bpmChange.Match(line); if (match.Success) { bpmChanges.Add(new BeatEvent(barToBeat.BeatAt(ParseMmm(match.Groups[1])), bpmDefinitions[ParseInt(match.Groups[2])])); continue; } //reach here, nothing matched, so we didn't read this line after all hasBeenRead[i] = false; } //We can now construct our BPM Graph, which means we now have everything needed to start parsing notes. bpmChanges.Sort((a, b) => a.beat.CompareTo(b.beat)); BpmGraph bpmGraph = BpmGraph.ParseBpm(bpmChanges, Array.Empty <BeatEvent>()); var notes = new List <RhythmEvent>(); var holdData = new Dictionary <int, List <PartialData> >(); var slideData = new Dictionary <int, List <PartialData> >(); var airData = new Dictionary <int, List <PartialData> >(); //PASS 3: read all note data for (int i = 0; i < data.Count; i++) { if (hasBeenRead[i]) { continue; } var line = data[i]; //assume we read this line (simplifies our code a bit) hasBeenRead[i] = true; //now try all regex rules for this stage in sequence: var match = _tap.Match(line); if (match.Success) { int barNum = ParseMmm(match.Groups[1]) + barOffset; int lane = ParseXY(match.Groups[2]); ProcessNotes(match.Groups[3], (barOff, type, width) => { double beat = barToBeat.BeatAt(barNum + barOff); var time = bpmGraph.FromBeat(beat); var pos = new LanePosition(lane * 2, width * 2); switch (type) { case 1: //standard notes.Add(new SimpleNote(time, pos, false)); break; case 2: //golden notes.Add(new SimpleNote(time, pos, true)); break; case 3: //swipe notes.Add(new SwipeNote(time, pos)); break; case 4: //mine notes.Add(new Mine(time, pos)); break; //TODO types 5 & 6 default: Debug.LogError($"Ignoring unknown tap type {type} at time {time} position {pos}"); break; } }); continue; } match = _arrow.Match(line); if (match.Success) { int barNum = ParseMmm(match.Groups[1]) + barOffset; int lane = ParseXY(match.Groups[2]); ProcessNotes(match.Groups[3], (barOff, type, width) => { double beat = barToBeat.BeatAt(barNum + barOff); var time = bpmGraph.FromBeat(beat); var pos = new LanePosition(lane * 2, width * 2); bool isUp = true; int arrowShift = 0; //convert the 6 cases to up/down/left/right/center information switch (type) { case 1: isUp = true; arrowShift = 0; break; case 2: isUp = false; arrowShift = 0; break; case 3: isUp = true; arrowShift = -1; break; case 4: isUp = true; arrowShift = +1; break; case 5: isUp = false; arrowShift = +1; //inverted because down break; case 6: isUp = false; arrowShift = -1; //inverted because down break; default: Debug.LogError($"Unknown Air Arrow {type} at time {time} position {pos}"); break; } notes.Add(new AirArrow(time, pos, isUp, arrowShift)); }); continue; } //matching holds, airholds and slides are basically exactly the same, the only thing that changes is the output array match = _hold.Match(line); if (match.Success) { ProcessChannelNotes(match, barOffset, barToBeat, bpmGraph, holdData); continue; } match = _airHold.Match(line); if (match.Success) { ProcessChannelNotes(match, barOffset, barToBeat, bpmGraph, airData); continue; } match = _slide.Match(line); if (match.Success) { ProcessChannelNotes(match, barOffset, barToBeat, bpmGraph, slideData); continue; } //reach here, nothing matched, so we didn't read this line after all hasBeenRead[i] = false; } //all note data has now been read. We'll now assemble all multi-part notes. //sort note data and store length so we can use this for lookups on start/end of holds (TODO) notes.Sort((a, b) => a.Time.Beats.CompareTo(b.Time.Beats)); int noteDataLength = notes.Count; //TODO a lot of code below for (air)holds/slides is shared, may be useful to combine these into a generic function //holds: foreach (var holdChannel in holdData.Values) { //first sort all hold data in this channel holdChannel.Sort((a, b) => a.Time.Beats.CompareTo(b.Time.Beats)); //now walk through each in sequence with a state machine to assemble the holds PartialData?startingPoint = null; foreach (var dataPoint in holdChannel) { switch (dataPoint.Type) { case 1: //start if (startingPoint != null) { Debug.LogError($"Hold started on channel with already active hold at {startingPoint?.Time}"); } startingPoint = dataPoint; break; case 2: //end if (startingPoint == null) { Debug.LogError($"Attempt to end hold at {dataPoint.Time} without a starting point."); continue; } var holdNote = new HoldNote(startingPoint.Value.Time, dataPoint.Pos, new SlidePoint[1]); holdNote.SlidePoints[0] = new SlidePoint(holdNote, dataPoint.Time, holdNote.Position); notes.Add(holdNote); startingPoint = null; break; case 3: //relay Debug.LogWarning($"Skipping hold relay point"); //TODO (will be fixed if we merge slide and hold parsing code) break; default: Debug.LogError($"Unknown hold point type {dataPoint.Type} found at {dataPoint.Time}"); break; } } } //air holds: foreach (var airChannel in airData.Values) { //first sort all hold data in this channel airChannel.Sort((a, b) => a.Time.Beats.CompareTo(b.Time.Beats)); //now walk through each in sequence with a state machine to assemble the holds PartialData?startingPoint = null; foreach (var dataPoint in airChannel) { switch (dataPoint.Type) { case 1: //start if (startingPoint != null) { Debug.LogError($"Air hold started on channel with already active hold at {startingPoint?.Time}"); } startingPoint = dataPoint; break; case 2: //end if (startingPoint == null) { Debug.LogError($"Attempt to end air hold at {dataPoint.Time} without a starting point."); continue; } var airHold = new AirHold(startingPoint.Value.Time, dataPoint.Pos, new SlidePoint[1]); airHold.SlidePoints[0] = new SlidePoint(airHold, dataPoint.Time, airHold.Position); notes.Add(airHold); notes.Add(new AirAction(dataPoint.Time, dataPoint.Pos)); startingPoint = null; break; case 3: //relay notes.Add(new AirAction(dataPoint.Time, dataPoint.Pos)); break; default: Debug.LogError($"Unknown hold point type {dataPoint.Type} found at {dataPoint.Time}"); break; } } } //slides: foreach (var slideChannel in slideData.Values) { //first sort all hold data in this channel slideChannel.Sort((a, b) => a.Time.Beats.CompareTo(b.Time.Beats)); //now walk through each in sequence with a state machine to assemble the holds var dataPoints = new List <PartialData>(); foreach (var dataPoint in slideChannel) { switch (dataPoint.Type) { case 1: //start if (dataPoints.Count > 0) { Debug.LogError($"Hold started on channel with already active slide at {dataPoints[0].Time}"); } dataPoints.Add(dataPoint); break; case 2: //end if (dataPoints.Count == 0) { Debug.LogError($"Attempt to end slide at {dataPoint.Time} without a starting point."); continue; } dataPoints.Add(dataPoint); //we now have all points, create a SlideNote from this: var slidePoints = new List <SlidePoint>(); var slideNote = new SlideNote(dataPoints[0].Time, dataPoints[0].Pos, null); Note previous = slideNote; SlidePoint.AnchorNote anchor = null; for (int i = 1; i < dataPoints.Count; i++) //start from 1, the initial point is the base SlideNote { var pointHere = dataPoints[i]; if (pointHere.Type == 4) { //anchor point anchor = new SlidePoint.AnchorNote(pointHere.Time, pointHere.Pos); continue; } var newPoint = new SlidePoint(previous, pointHere.Time, pointHere.Pos); newPoint.AnchorPoint = anchor; //writes anchor if set, null otherwise anchor = null; newPoint.Visible = pointHere.Type == 3; //set visible/invisible slidePoints.Add(newPoint); previous = newPoint; } slideNote.SlidePoints = slidePoints.ToArray(); notes.Add(slideNote); dataPoints.Clear(); break; case 3: //relay case 4: //bezier anchor case 5: //invisible relay if (dataPoints.Count == 0) { Debug.LogError($"Attempt to add points to slide at {dataPoint.Time} without a starting point."); continue; } dataPoints.Add(dataPoint); break; default: Debug.LogError($"Unknown slide point type {dataPoint.Type} found at {dataPoint.Time}"); break; } } } //finally, sort the notes and return the finished chart notes.Sort((a, b) => a.Time.Beats.CompareTo(b.Time.Beats)); //TODO store difficulty in here var chart = new Chart("undefined", bpmGraph, notes); song.Charts = new List <Chart>(); song.Charts.Add(chart); return(song); }
public static double GetNoteDurationInBeatLength(HoldNote holdNote, ManiaBeatmap beatmap) { double beatLength = beatmap.ControlPointInfo.TimingPointAt(holdNote.StartTime).BeatLength; return(holdNote.Duration / beatLength); }
public ReversibleAddHoldNote(S2VXStory story, HoldNote note, EditorScreen editor) { Story = story; Note = note; Editor = editor; }
private void ConvertNotes(List <Tuple <int, string> > pulseToKeysoundIndex, string channel, int lane) { foreach (Tuple <int, string> tuple in pulseToKeysoundIndex) { int pulse = tuple.Item1; string index = tuple.Item2; // Is this note an LN closer? bool lnCloser = false; if (Regex.IsMatch(channel, @"[1-4].") && index == longNoteCloser && channelToLastNote.ContainsKey(channel) && channelToLastNote[channel] != null) { lnCloser = true; } else if (Regex.IsMatch(channel, @"[5-6].") && channelToLastNote.ContainsKey(channel) && channelToLastNote[channel] != null) { lnCloser = true; } if (lnCloser) { // Turn the last note in this channel into a long note. Note lastNote = channelToLastNote[channel]; int duration = pulse - lastNote.pulse; pattern.notes.Remove(lastNote); HoldNote holdNote = new HoldNote() { type = NoteType.Hold, pulse = lastNote.pulse, lane = lastNote.lane, sound = lastNote.sound, duration = duration }; pattern.notes.Add(holdNote); // On channels 5x and 6x, prepare for the next note. if (Regex.IsMatch(channel, @"[5-6].")) { channelToLastNote.Remove(channel); } } else { // Add note and mark as last note. string filename = ""; if (keysoundIndexToName.ContainsKey(index)) { filename = keysoundIndexToName[index]; } Note note = new Note() { type = NoteType.Basic, pulse = pulse, lane = lane, sound = filename }; pattern.notes.Add(note); channelToLastNote[channel] = note; } } }
public NoteTimeInfo(HoldNote holdNote) { Type = "HoldNote"; StartTime = holdNote.HitTime; EndTime = holdNote.EndTime; }
private void createPlayfieldWithNotes(bool inverted = false) { Clear(); var rateAdjustClock = new StopwatchClock(true) { Rate = 1 }; var inputManager = new ManiaInputManager(maniaRuleset, 4) { RelativeSizeAxes = Axes.Both }; Add(inputManager); ManiaPlayfield playfield; var stages = new List <StageDefinition> { new StageDefinition { Columns = 4 }, }; inputManager.Add(playfield = new ManiaPlayfield(stages) { Anchor = Anchor.Centre, Origin = Anchor.Centre, Clock = new FramedClock(rateAdjustClock) }); playfield.Inverted.Value = inverted; for (double t = start_time; t <= start_time + duration; t += 100) { var note1 = new Note { StartTime = t, Column = 0 }; var note2 = new Note { StartTime = t, Column = 3 }; note1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); note2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); playfield.Add(new DrawableNote(note1, ManiaAction.Key1)); playfield.Add(new DrawableNote(note2, ManiaAction.Key4)); } var holdNote1 = new HoldNote { StartTime = start_time, Duration = duration, Column = 1 }; var holdNote2 = new HoldNote { StartTime = start_time, Duration = duration, Column = 2 }; holdNote1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); holdNote2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); playfield.Add(new DrawableHoldNote(holdNote1, ManiaAction.Key2)); playfield.Add(new DrawableHoldNote(holdNote2, ManiaAction.Key3)); }
public void Initialize(Scan scanRef, Scanline scanlineRef, HoldNote holdNote) { GetComponent <HoldTrailManager>().Initialize( scanRef, scanlineRef, holdNote); }