/// <summary> /// Set the <see cref="Event"/> sets with specified array of <see cref="Event"/> for specified <see cref="Difficulty"/>. /// <para> /// This method will recalculate <see cref="EventCount"/>, <see cref="NoteCount"/>, <see cref="MeasureCount"/>, /// <see cref="BlockCount"/>, <see cref="BlockOffset"/> and <see cref="CoverArtOffset"/>. /// </para> /// </summary> /// <param name="difficulty">Specifies the <see cref="Difficulty"/> to set.</param> /// <param name="events">New array of <see cref="Event"/> to subtitue the current event sets.</param> public void SetEvents(OJN.Difficulty difficulty, Event[] events) { Events[difficulty] = events; EventCount[difficulty] = events.Length; NoteCount[difficulty] = events.Where((ev) => ev.Channel != Event.ChannelType.Measurement && ev.Channel != Event.ChannelType.BPM && ev.Channel != Event.ChannelType.BGM ).Count(); MeasureCount[difficulty] = events.Max((ev) => ev.Measure) + 1; // Reset offset foreach (var diff in Enum.GetValues(typeof(OJN.Difficulty)) as OJN.Difficulty[]) { // Skip MX as we dont really have it in current implementation if (diff == Difficulty.MX) { continue; } // Get initial offset, typically offset or previous difficulty offset; // We'll calculate the rest offset later int offset = 300; if (diff == Difficulty.EX) { BlockOffset[diff] = offset; } else { BlockOffset[diff] = BlockOffset[diff - 1]; } // Get the number of blocks BlockCount[diff] = Events[diff].GroupBy((ev) => new { ev.Measure, ev.Tempo, ev.LaneIndex }).Count(); // No need to calculate the previous block size if it's EX difficulty // Because it is first difficulty and no previous difficulty if (diff == Difficulty.EX) { continue; } // Calculate total block size of previous difficulty to get block offset of current difficulty var blocks = Events[diff - 1].GroupBy((ev) => new { ev.Measure, ev.Tempo, ev.LaneIndex }); foreach (var block in blocks) { // Calculate the event size, one event worth 4 bytes // Regardless it is empty event or not // Block header also contains 8 bytes BlockOffset[diff] += 8 + (block.Count() * 4); } // Calculate the HX block size as well to get CoverArtOffset if (diff == Difficulty.HX) { blocks = Events[diff].GroupBy((ev) => new { ev.Measure, ev.Tempo, ev.LaneIndex }); CoverArtOffset = BlockOffset[diff]; foreach (var block in blocks) { // Again, Calculate the block size from the sets of events. CoverArtOffset += 8 + (block.Count() * 4); } } } }
/// <summary> /// Gets an array of <see cref="Event"/> of specified <see cref="Difficulty"/>. /// </summary> /// <param name="difficulty">Specifies the <see cref="Difficulty"/> of <see cref="Event"/> to retrieve.</param> /// <returns>An array of <see cref="Event"/> of specified <see cref="Difficulty"/>.</returns> public Event[] GetEvents(OJN.Difficulty difficulty) { return(Events[difficulty]); }