Пример #1
0
        public void CreateTarget(QNT_Timestamp time, TargetBehavior behavior, TargetHandType hand, Vector2?position = null)
        {
            if (!position.HasValue)
            {
                position = new Vector2(0, 0);
            }

            TargetData data = new TargetData();

            data.x        = position.Value.x;
            data.y        = position.Value.y;
            data.handType = hand;
            data.behavior = behavior;
            data.SetTimeFromAction(time);

            var action = new NRActionAddNote {
                targetData = data
            };

            timeline.Tools.undoRedoManager.AddAction(action);
        }
Пример #2
0
        public static void CalculateChainNotes(TargetData parentData)
        {
            if (parentData.behavior != TargetBehavior.NR_Pathbuilder)
            {
                return;
            }

            if (parentData.pathBuilderData.createdNotes)
            {
                parentData.pathBuilderData.generatedNotes.ForEach(t => {
                    timeline.DeleteTargetFromAction(t);
                });
                parentData.pathBuilderData.createdNotes = false;
            }

            //No notes can be generated
            if (parentData.beatLength.tick == 0)
            {
                return;
            }

            parentData.pathBuilderData.generatedNotes = new List <TargetData>();

            foreach (TargetData data in parentData.pathBuilderData.parentNotes)
            {
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                /////////                                            WARNING!                                                      /////////
                /////////       Chainging this calculation breaks backwards compatibility with saves of older NotReaper versions!  /////////
                /////////                    Make sure to update NRCueData.Version, and handle an upgrade path!                    /////////
                ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                //Generate first note at the start
                TargetData firstData = new TargetData();
                firstData.behavior = data.pathBuilderData.behavior;
                firstData.velocity = data.pathBuilderData.velocity;
                firstData.handType = data.pathBuilderData.handType;

                //Force set the time, since these transient notes will get generated for all pathbuilders in repeaters
                firstData.SetTimeFromAction(data.time);

                firstData.position = data.position;
                data.pathBuilderData.generatedNotes.Add(firstData);

                //We increment as if all these values were for 1/4 notes over 4 beats, makes the ui much better
                float quarterIncrConvert = (4.0f / data.pathBuilderData.interval) * (Constants.PulsesPerQuarterNote * 4.0f / data.beatLength.tick);

                //Generate new notes
                Vector2 currentPos   = data.position;
                Vector2 currentDir   = new Vector2(Mathf.Sin(data.pathBuilderData.initialAngle * Mathf.Deg2Rad), Mathf.Cos(data.pathBuilderData.initialAngle * Mathf.Deg2Rad));
                float   currentAngle = (data.pathBuilderData.angle / 4) * quarterIncrConvert;
                float   currentStep  = data.pathBuilderData.stepDistance * quarterIncrConvert;

                TargetBehavior generatedBehavior = data.pathBuilderData.behavior;
                if (generatedBehavior == TargetBehavior.ChainStart)
                {
                    generatedBehavior = TargetBehavior.Chain;
                }

                TargetVelocity generatedVelocity = data.pathBuilderData.velocity;
                if (generatedVelocity == TargetVelocity.ChainStart)
                {
                    generatedVelocity = TargetVelocity.Chain;
                }

                for (int i = 1; i <= (data.beatLength.tick / (float)Constants.PulsesPerQuarterNote) * (data.pathBuilderData.interval / 4.0f); ++i)
                {
                    currentPos += currentDir * currentStep;
                    currentDir  = currentDir.Rotate(currentAngle);

                    currentAngle += (data.pathBuilderData.angleIncrement / 4) * quarterIncrConvert;
                    currentStep  += data.pathBuilderData.stepIncrement * quarterIncrConvert;

                    TargetData newData = new TargetData();
                    newData.behavior = generatedBehavior;
                    newData.velocity = generatedVelocity;
                    newData.handType = data.pathBuilderData.handType;

                    //Force set the time, since these transient notes will get generated for all pathbuilders in repeaters
                    newData.SetTimeFromAction(data.time + QNT_Duration.FromBeatTime(i * (4.0f / data.pathBuilderData.interval)));

                    newData.position = currentPos;
                    data.pathBuilderData.generatedNotes.Add(newData);
                }
            }

            parentData.pathBuilderData.OnFinishRecalculate();
        }