private static void ProcessNotesInTimeRow(List <NoteData> notes) { List <CustomNoteData> customNotes = notes.Cast <CustomNoteData>().ToList(); ProcessFlipData(customNotes, false); _numberOfNotesInLines.Clear(); for (int i = 0; i < customNotes.Count; i++) { CustomNoteData noteData = customNotes[i]; dynamic dynData = noteData.customData; IEnumerable <float?> position = ((List <object>)Trees.at(dynData, POSITION))?.Select(n => n.ToNullableFloat()); float lineIndex = position?.ElementAt(0) ?? noteData.lineIndex; float lineLayer = position?.ElementAt(1) ?? (float)noteData.noteLineLayer; if (_numberOfNotesInLines.TryGetValue(lineIndex, out float num)) { Dictionary <float, float> numberOfNotesInLines = _numberOfNotesInLines; float num2 = Math.Max(numberOfNotesInLines[lineIndex], 0) + Math.Min(lineLayer, 1); dynData.startNoteLineLayer = num2; numberOfNotesInLines[lineIndex] = num2; } else { float startLineLayer = Math.Min(lineLayer, 0); _numberOfNotesInLines[lineIndex] = startLineLayer; dynData.startNoteLineLayer = startLineLayer; } } }
private CNVColorManager(ColorNoteVisuals cnv, NoteController nc) { _cnv = cnv; _nc = nc; _colorManager = _colorManagerAccessor(ref cnv); if (nc.noteData is CustomNoteData customNoteData) { _noteData = customNoteData; } }
private static void Postfix(List <NoteData> notes) { if (notes.FirstOrDefault() is CustomNoteData) { List <CustomNoteData> customNotes = notes.Cast <CustomNoteData>().ToList(); _notesInColumns.Clear(); for (int i = 0; i < customNotes.Count; i++) { CustomNoteData noteData = customNotes[i]; IEnumerable <float?> position = ((List <object>)Trees.at(noteData.customData, POSITION))?.Select(n => n.ToNullableFloat()); float lineIndex = position?.ElementAtOrDefault(0) ?? (noteData.lineIndex - 2); float lineLayer = position?.ElementAtOrDefault(1) ?? (float)noteData.noteLineLayer; if (!_notesInColumns.TryGetValue(lineIndex, out List <CustomNoteData> list)) { list = new List <CustomNoteData>(); _notesInColumns.Add(lineIndex, list); } bool flag = false; for (int k = 0; k < list.Count; k++) { IEnumerable <float?> listPosition = ((List <object>)Trees.at(list[k].customData, POSITION))?.Select(n => n.ToNullableFloat()); float listLineLayer = listPosition?.ElementAtOrDefault(1) ?? (float)list[k].noteLineLayer; if (listLineLayer > lineLayer) { list.Insert(k, noteData); flag = true; break; } } if (!flag) { list.Add(noteData); } } foreach (KeyValuePair <float, List <CustomNoteData> > keyValue in _notesInColumns) { List <CustomNoteData> list2 = keyValue.Value; for (int m = 0; m < list2.Count; m++) { list2[m].customData.startNoteLineLayer = m; } } // Process flip data List <CustomNoteData> flipNotes = new List <CustomNoteData>(customNotes); for (int i = flipNotes.Count - 1; i >= 0; i--) { dynamic dynData = flipNotes[i].customData; IEnumerable <float?> flip = ((List <object>)Trees.at(dynData, FLIP))?.Select(n => n.ToNullableFloat()); float?flipX = flip?.ElementAtOrDefault(0); float?flipY = flip?.ElementAtOrDefault(1); if (flipX.HasValue || flipY.HasValue) { if (flipX.HasValue) { dynData.flipLineIndex = flipX.Value; } if (flipY.HasValue) { dynData.flipYSide = flipY.Value; } flipNotes.Remove(flipNotes[i]); } } flipNotes.ForEach(c => c.customData.flipYSide = 0); } }
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter private static void Prefix(NoteController __instance, NoteData ____noteData, NoteMovement ____noteMovement) #pragma warning restore SA1313 // Parameter names should begin with lower-case letter { if (____noteData is CustomNoteData customData) { CustomNoteData = customData; dynamic dynData = customData.customData; Track track = Trees.at(dynData, "track"); dynamic animationObject = Trees.at(dynData, "_animation"); if (track != null || animationObject != null) { NoteJump noteJump = NoteControllerInit._noteJumpAccessor(ref ____noteMovement); NoteFloorMovement floorMovement = NoteControllerInit._noteFloorMovementAccessor(ref ____noteMovement); // idk i just copied base game time float jumpDuration = _jumpDurationAccessor(ref noteJump); float elapsedTime = _audioTimeSyncControllerAccessor(ref noteJump).songTime - (____noteData.time - (jumpDuration * 0.5f)); elapsedTime = NoteJumpManualUpdate.NoteJumpTimeAdjust(elapsedTime, jumpDuration); float normalTime = elapsedTime / jumpDuration; AnimationHelper.GetObjectOffset(animationObject, track, normalTime, out Vector3? positionOffset, out Quaternion? rotationOffset, out Vector3? scaleOffset, out Quaternion? localRotationOffset, out float?dissolve, out float?dissolveArrow, out float?cuttable); if (positionOffset.HasValue) { Vector3 moveStartPos = Trees.at(dynData, "moveStartPos"); Vector3 moveEndPos = Trees.at(dynData, "moveEndPos"); Vector3 jumpEndPos = Trees.at(dynData, "jumpEndPos"); Vector3 offset = positionOffset.Value; _floorStartPosAccessor(ref floorMovement) = moveStartPos + offset; _floorEndPosAccessor(ref floorMovement) = moveEndPos + offset; _jumpStartPosAccessor(ref noteJump) = moveEndPos + offset; _jumpEndPosAccessor(ref noteJump) = jumpEndPos + offset; } Transform transform = __instance.transform; if (rotationOffset.HasValue || localRotationOffset.HasValue) { Quaternion worldRotation = Trees.at(dynData, "worldRotation"); Quaternion localRotation = Trees.at(dynData, "localRotation"); Quaternion worldRotationQuatnerion = worldRotation; if (rotationOffset.HasValue) { worldRotationQuatnerion *= rotationOffset.Value; Quaternion inverseWorldRotation = Quaternion.Euler(-worldRotationQuatnerion.eulerAngles); NoteControllerInit._worldRotationJumpAccessor(ref noteJump) = worldRotationQuatnerion; NoteControllerInit._inverseWorldRotationJumpAccessor(ref noteJump) = inverseWorldRotation; NoteControllerInit._worldRotationFloorAccessor(ref floorMovement) = worldRotationQuatnerion; NoteControllerInit._inverseWorldRotationFloorAccessor(ref floorMovement) = inverseWorldRotation; } worldRotationQuatnerion *= localRotation; if (localRotationOffset.HasValue) { worldRotationQuatnerion *= localRotationOffset.Value; } transform.localRotation = worldRotationQuatnerion; } if (scaleOffset.HasValue) { transform.localScale = scaleOffset.Value; } if (dissolve.HasValue) { CutoutEffect cutoutEffect = Trees.at(dynData, "cutoutEffect"); if (cutoutEffect == null) { BaseNoteVisuals baseNoteVisuals = __instance.gameObject.GetComponent <BaseNoteVisuals>(); CutoutAnimateEffect cutoutAnimateEffect = _noteCutoutAnimateEffectAccessor(ref baseNoteVisuals); CutoutEffect[] cutoutEffects = _cutoutEffectAccessor(ref cutoutAnimateEffect); cutoutEffect = cutoutEffects.First(n => n.name != "NoteArrow"); // 1.11 NoteArrow has been added to the CutoutAnimateEffect and we don't want that dynData.cutoutAnimateEffect = cutoutEffect; } cutoutEffect.SetCutout(1 - dissolve.Value); } if (dissolveArrow.HasValue && __instance.noteData.noteType != NoteType.Bomb) { DisappearingArrowController disappearingArrowController = Trees.at(dynData, "disappearingArrowController"); if (disappearingArrowController == null) { disappearingArrowController = __instance.gameObject.GetComponent <DisappearingArrowController>(); dynData.disappearingArrowController = disappearingArrowController; } disappearingArrowController.SetArrowTransparency(dissolveArrow.Value); } if (cuttable.HasValue) { bool enabled = cuttable.Value >= 1; switch (__instance) { case GameNoteController gameNoteController: BoxCuttableBySaber bigCuttableBySaber = _gameNoteBigCuttableAccessor(ref gameNoteController); if (bigCuttableBySaber.enabled != enabled) { bigCuttableBySaber.enabled = enabled; _gameNoteSmallCuttableAccessor(ref gameNoteController).enabled = enabled; } break; case BombNoteController bombNoteController: CuttableBySaber boxCuttableBySaber = _bombNoteCuttableAccessor(ref bombNoteController); if (boxCuttableBySaber.enabled != enabled) { boxCuttableBySaber.enabled = enabled; } break; } } } } }
private static void Prefix(List <NoteData> notesInTimeRow) { if (notesInTimeRow.FirstOrDefault() is CustomNoteData) { List <CustomNoteData> notesToSetFlip = new List <CustomNoteData>(); Dictionary <float, List <CustomNoteData> > notesInColumns = new Dictionary <float, List <CustomNoteData> >(); for (int i = 0; i < notesInTimeRow.Count; i++) { CustomNoteData noteData = (CustomNoteData)notesInTimeRow[i]; Dictionary <string, object?> dynData = noteData.customData; IEnumerable <float?>?position = dynData.GetNullableFloats(POSITION); float lineIndex = position?.ElementAtOrDefault(0) ?? (noteData.lineIndex - 2); float lineLayer = position?.ElementAtOrDefault(1) ?? (float)noteData.noteLineLayer; if (!notesInColumns.TryGetValue(lineIndex, out List <CustomNoteData> list)) { list = new List <CustomNoteData>(1); notesInColumns.Add(lineIndex, list); } bool flag = false; for (int k = 0; k < list.Count; k++) { IEnumerable <float?>?listPosition = list[k].customData.GetNullableFloats(POSITION); float listLineLayer = listPosition?.ElementAtOrDefault(1) ?? (float)list[k].noteLineLayer; if (listLineLayer > lineLayer) { list.Insert(k, noteData); flag = true; break; } } if (!flag) { list.Add(noteData); } // Flippy stuff IEnumerable <float?>?flip = dynData.GetNullableFloats(FLIP); float?flipX = flip?.ElementAtOrDefault(0); float?flipY = flip?.ElementAtOrDefault(1); if (flipX.HasValue || flipY.HasValue) { if (flipX.HasValue) { dynData["flipLineIndex"] = flipX.Value; } if (flipY.HasValue) { dynData["flipYSide"] = flipY.Value; } } else if (!dynData.ContainsKey("flipYSide")) { notesToSetFlip.Add(noteData); } } foreach (KeyValuePair <float, List <CustomNoteData> > keyValue in notesInColumns) { List <CustomNoteData> list2 = keyValue.Value; for (int m = 0; m < list2.Count; m++) { list2[m].customData["startNoteLineLayer"] = m; } } // Process flip data notesToSetFlip.ForEach(c => c.customData["flipYSide"] = 0); } }