internal static void GetObjectOffset(NoodleObjectData.AnimationObjectData animationObject, Track track, float time, out Vector3?positionOffset, out Quaternion?rotationOffset, out Vector3?scaleOffset, out Quaternion?localRotationOffset, out float?dissolve, out float?dissolveArrow, out float?cuttable)
        {
            Vector3?   pathPosition      = animationObject.LocalPosition?.Interpolate(time) ?? TryGetVector3PathProperty(track, POSITION, time);
            Quaternion?pathRotation      = animationObject.LocalRotation?.InterpolateQuaternion(time) ?? TryGetQuaternionPathProperty(track, ROTATION, time);
            Vector3?   pathScale         = animationObject.LocalScale?.Interpolate(time) ?? TryGetVector3PathProperty(track, SCALE, time);
            Quaternion?pathLocalRotation = animationObject.LocalLocalRotation?.InterpolateQuaternion(time) ?? TryGetQuaternionPathProperty(track, LOCALROTATION, time);
            float?     pathDissolve      = animationObject.LocalDissolve?.InterpolateLinear(time) ?? TryGetLinearPathProperty(track, DISSOLVE, time);
            float?     pathDissolveArrow = animationObject.LocalDissolveArrow?.InterpolateLinear(time) ?? TryGetLinearPathProperty(track, DISSOLVEARROW, time);
            float?     pathCuttable      = animationObject.LocalCuttable?.InterpolateLinear(time) ?? TryGetLinearPathProperty(track, CUTTABLE, time);

            positionOffset      = SumVectorNullables((Vector3?)TryGetPropertyAsObject(track, POSITION), pathPosition) * NoteLinesDistance;
            rotationOffset      = MultQuaternionNullables((Quaternion?)TryGetPropertyAsObject(track, ROTATION), pathRotation);
            scaleOffset         = MultVectorNullables((Vector3?)TryGetPropertyAsObject(track, SCALE), pathScale);
            localRotationOffset = MultQuaternionNullables((Quaternion?)TryGetPropertyAsObject(track, LOCALROTATION), pathLocalRotation);
            dissolve            = MultFloatNullables((float?)TryGetPropertyAsObject(track, DISSOLVE), pathDissolve);
            dissolveArrow       = MultFloatNullables((float?)TryGetPropertyAsObject(track, DISSOLVEARROW), pathDissolveArrow);
            cuttable            = MultFloatNullables((float?)TryGetPropertyAsObject(track, CUTTABLE), pathCuttable);

            if (NoodleController.LeftHandedMode)
            {
                MirrorVectorNullable(ref positionOffset);
                MirrorQuaternionNullable(ref rotationOffset);
                MirrorQuaternionNullable(ref localRotationOffset);
            }
        }
        internal static void GetDefinitePositionOffset(NoodleObjectData.AnimationObjectData animationObject, Track track, float time, out Vector3?definitePosition)
        {
            PointDefinition localDefinitePosition = animationObject.LocalDefinitePosition;

            Vector3?pathDefinitePosition = localDefinitePosition?.Interpolate(time) ?? TryGetVector3PathProperty(track, DEFINITEPOSITION, time);

            if (pathDefinitePosition.HasValue)
            {
                Vector3?pathPosition   = animationObject.LocalPosition?.Interpolate(time) ?? TryGetVector3PathProperty(track, POSITION, time);
                Vector3?positionOffset = SumVectorNullables((Vector3?)TryGetPropertyAsObject(track, POSITION), pathPosition);
                definitePosition = SumVectorNullables(positionOffset, pathDefinitePosition) * NoteLinesDistance;

                if (NoodleController.LeftHandedMode)
                {
                    MirrorVectorNullable(ref definitePosition);
                }
            }
            else
            {
                definitePosition = null;
            }
        }
Exemple #3
0
        private static void Prefix(NoteController __instance, NoteData ____noteData, NoteMovement ____noteMovement)
        {
            if (__instance is MultiplayerConnectedPlayerNoteController)
            {
                NoodleData = null;
                return;
            }

            NoodleData = NoodleObjectDatas[____noteData];
            NoodleNoteData noodleData = (NoodleNoteData)NoodleData;

            Track track = noodleData.Track;

            NoodleObjectData.AnimationObjectData animationObject = noodleData.AnimationObject;
            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 = noodleData.MoveStartPos;
                    Vector3 moveEndPos   = noodleData.MoveEndPos;
                    Vector3 jumpEndPos   = noodleData.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 = noodleData.WorldRotation;
                    Quaternion localRotation = noodleData.LocalRotation;

                    Quaternion worldRotationQuatnerion = worldRotation;
                    if (rotationOffset.HasValue)
                    {
                        worldRotationQuatnerion *= rotationOffset.Value;
                        Quaternion inverseWorldRotation = Quaternion.Inverse(worldRotationQuatnerion);
                        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 = noodleData.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
                        noodleData.CutoutEffect = cutoutEffect;
                    }

                    cutoutEffect.SetCutout(1 - dissolve.Value);
                }

                if (dissolveArrow.HasValue && __instance.noteData.colorType != ColorType.None)
                {
                    MonoBehaviour disappearingArrowController = noodleData.DisappearingArrowController;
                    if (disappearingArrowController == null)
                    {
                        disappearingArrowController = __instance.gameObject.GetComponent <DisappearingArrowControllerBase <GameNoteController> >();
                        if (disappearingArrowController == null)
                        {
                            disappearingArrowController = __instance.gameObject.GetComponent <DisappearingArrowControllerBase <MultiplayerConnectedPlayerGameNoteController> >();
                        }

                        noodleData.DisappearingArrowController = disappearingArrowController;
                        noodleData.DisappearingArrowMethod     = GetSetArrowTransparency(disappearingArrowController.GetType());
                    }

                    // gross nasty reflection
                    noodleData.DisappearingArrowMethod.Invoke(disappearingArrowController, new object[] { dissolveArrow.Value });
                }

                if (cuttable.HasValue)
                {
                    bool enabled = cuttable.Value >= 1;

                    switch (__instance)
                    {
                    case GameNoteController gameNoteController:
                        BoxCuttableBySaber[] bigCuttableBySaberList = _gameNoteBigCuttableAccessor(ref gameNoteController);
                        foreach (BoxCuttableBySaber bigCuttableBySaber in bigCuttableBySaberList)
                        {
                            if (bigCuttableBySaber.canBeCut != enabled)
                            {
                                bigCuttableBySaber.canBeCut = enabled;
                            }
                        }

                        BoxCuttableBySaber[] smallCuttableBySaberList = _gameNoteSmallCuttableAccessor(ref gameNoteController);
                        foreach (BoxCuttableBySaber smallCuttableBySaber in smallCuttableBySaberList)
                        {
                            if (smallCuttableBySaber.canBeCut != enabled)
                            {
                                smallCuttableBySaber.canBeCut = enabled;
                            }
                        }

                        break;

                    case BombNoteController bombNoteController:
                        CuttableBySaber boxCuttableBySaber = _bombNoteCuttableAccessor(ref bombNoteController);
                        if (boxCuttableBySaber.canBeCut != enabled)
                        {
                            boxCuttableBySaber.canBeCut = enabled;
                        }

                        break;
                    }
                }
            }
        }
Exemple #4
0
        private static void Prefix(
            ObstacleController __instance,
            ObstacleData ____obstacleData,
            AudioTimeSyncController ____audioTimeSyncController,
            float ____startTimeOffset,
            ref Vector3 ____startPos,
            ref Vector3 ____midPos,
            ref Vector3 ____endPos,
            float ____move1Duration,
            float ____move2Duration,
            float ____obstacleDuration,
            ref Quaternion ____worldRotation,
            ref Quaternion ____inverseWorldRotation,
            ref Bounds ____bounds)
        {
            if (__instance is MultiplayerConnectedPlayerObstacleController)
            {
                return;
            }

            NoodleObstacleData noodleData = (NoodleObstacleData)NoodleObjectDatas[____obstacleData];

            Track track = noodleData.Track;

            NoodleObjectData.AnimationObjectData animationObject = noodleData.AnimationObject;
            if (track != null || animationObject != null)
            {
                // idk i just copied base game time
                float elapsedTime = ____audioTimeSyncController.songTime - ____startTimeOffset;
                float normalTime  = (elapsedTime - ____move1Duration) / (____move2Duration + ____obstacleDuration);

                AnimationHelper.GetObjectOffset(animationObject, track, normalTime, out Vector3? positionOffset, out Quaternion? rotationOffset, out Vector3? scaleOffset, out Quaternion? localRotationOffset, out float?dissolve, out float?_, out float?cuttable);

                if (positionOffset.HasValue)
                {
                    Vector3 startPos = noodleData.StartPos;
                    Vector3 midPos   = noodleData.MidPos;
                    Vector3 endPos   = noodleData.EndPos;

                    Vector3 offset = positionOffset.Value;
                    ____startPos = startPos + offset;
                    ____midPos   = midPos + offset;
                    ____endPos   = endPos + offset;
                }

                Transform transform = __instance.transform;

                if (rotationOffset.HasValue || localRotationOffset.HasValue)
                {
                    Quaternion worldRotation = noodleData.WorldRotation;
                    Quaternion localRotation = noodleData.LocalRotation;

                    Quaternion worldRotationQuatnerion = worldRotation;
                    if (rotationOffset.HasValue)
                    {
                        worldRotationQuatnerion *= rotationOffset.Value;
                        Quaternion inverseWorldRotation = Quaternion.Inverse(worldRotationQuatnerion);
                        ____worldRotation        = worldRotationQuatnerion;
                        ____inverseWorldRotation = inverseWorldRotation;
                    }

                    worldRotationQuatnerion *= localRotation;

                    if (localRotationOffset.HasValue)
                    {
                        worldRotationQuatnerion *= localRotationOffset.Value;
                    }

                    transform.localRotation = worldRotationQuatnerion;
                }

                bool cuttableEnabled = true;
                if (cuttable.HasValue)
                {
                    cuttableEnabled = cuttable.Value >= 1;
                    if (cuttableEnabled)
                    {
                        if (____bounds.size != _vectorZero)
                        {
                            ____bounds.size = _vectorZero;
                        }
                    }
                    else
                    {
                        Vector3 boundsSize = noodleData.BoundsSize;
                        if (____bounds.size != boundsSize)
                        {
                            ____bounds.size = boundsSize;
                        }
                    }
                }

                if (scaleOffset.HasValue)
                {
                    transform.localScale = scaleOffset.Value;
                }

                if (dissolve.HasValue)
                {
                    CutoutAnimateEffect cutoutAnimateEffect = noodleData.CutoutAnimateEffect;
                    if (cutoutAnimateEffect == null)
                    {
                        ObstacleDissolve obstacleDissolve = __instance.gameObject.GetComponent <ObstacleDissolve>();
                        cutoutAnimateEffect            = _obstacleCutoutAnimateEffectAccessor(ref obstacleDissolve);
                        noodleData.CutoutAnimateEffect = cutoutAnimateEffect;
                    }

                    cutoutAnimateEffect.SetCutout(1 - dissolve.Value);
                }
            }

            if (noodleData.DoUnhide)
            {
                __instance.hide = false;
            }
        }