public void MoveSelection(float beats, bool snapObjects = false)
    {
        List <BeatmapAction> allActions = new List <BeatmapAction>();

        foreach (BeatmapObject data in SelectedObjects)
        {
            BeatmapObjectContainerCollection collection = BeatmapObjectContainerCollection.GetCollectionForType(data.beatmapType);
            BeatmapObject original = BeatmapObject.GenerateCopy(data);

            collection.LoadedObjects.Remove(data);
            data._time += beats;
            if (snapObjects)
            {
                data._time = Mathf.Round(beats / (1f / atsc.gridMeasureSnapping)) * (1f / atsc.gridMeasureSnapping);
            }
            collection.LoadedObjects.Add(data);

            if (collection.LoadedContainers.TryGetValue(data, out BeatmapObjectContainer con))
            {
                con.UpdateGridPosition();
            }

            if (collection is NotesContainer notesContainer)
            {
                notesContainer.RefreshSpecialAngles(original, false, false);
                notesContainer.RefreshSpecialAngles(data, false, false);
            }

            allActions.Add(new BeatmapObjectModifiedAction(data, data, original, "", true));
        }
        BeatmapActionContainer.AddAction(new ActionCollectionAction(allActions, true, true, "Shifted a selection of objects."));
        BeatmapObjectContainerCollection.RefreshAllPools();
    }
    /// <summary>
    /// Deletes a <see cref="BeatmapObject"/>.
    /// </summary>
    /// <param name="obj">To delete.</param>
    /// <param name="triggersAction">Whether or not it triggers a <see cref="BeatmapObjectDeletionAction"/></param>
    /// <param name="refreshesPool">Whether or not the pool will be refreshed as a result of this deletion.</param>
    /// <param name="comment">A comment that provides further description on why it was deleted.</param>
    public void DeleteObject(BeatmapObject obj, bool triggersAction = true, bool refreshesPool = true, string comment = "No comment.")
    {
        var removed  = UnsortedObjects.Remove(obj);
        var removed2 = LoadedObjects.Remove(obj);

        if (removed && removed2)
        {
            //Debug.Log($"Deleting container with hash code {toDelete.GetHashCode()}");
            SelectionController.Deselect(obj, triggersAction);
            if (triggersAction)
            {
                BeatmapActionContainer.AddAction(new BeatmapObjectDeletionAction(obj, comment));
            }
            RecycleContainer(obj);
            if (refreshesPool)
            {
                RefreshPool();
            }
            OnObjectDelete(obj);
        }
        else
        {
            // The objects are not in the collection, but are still being removed.
            // This could be because of ghost blocks, so let's try forcefully recycling that container.
            Debug.LogError($"Object could not be deleted, please report this ({removed}, {removed2})");
        }
    }
    public void TweakValue(BeatmapEventContainer e, int modifier)
    {
        BeatmapObject original = BeatmapObject.GenerateCopy(e.objectData);

        e.eventData._value += modifier;

        if (e.eventData._value == 4 && !e.eventData.IsUtilityEvent)
        {
            e.eventData._value += modifier;
        }

        if (e.eventData._value < 0)
        {
            e.eventData._value = 0;
        }

        if (!e.eventData.IsLaserSpeedEvent)
        {
            if (e.eventData._value > 7)
            {
                e.eventData._value = 7;
            }
        }

        if (e.eventData.IsRotationEvent)
        {
            tracksManager?.RefreshTracks();
        }
        eventAppearanceSO.SetEventAppearance(e);
        BeatmapActionContainer.AddAction(new BeatmapObjectModifiedAction(e.objectData, e.objectData, original));
    }
    public void ObjectWasSelected()
    {
        queuedUpdate = !IsActive;
        if (queuedUpdate)
        {
            return;
        }

        if (!SelectionController.HasSelectedObjects())
        {
            isEditing = false;
            return;
        }
        BeatmapActionContainer.RemoveAllActionsOfType <NodeEditorTextChangedAction>();

        isEditing = true;
        if (!Settings.Instance.NodeEditor_UseKeybind)
        {
            StopAllCoroutines();
            closeButton.gameObject.SetActive(false);
            StartCoroutine(UpdateGroup(true, transform as RectTransform));
            if (firstActive)
            {
                firstActive = false;
                PersistentUI.Instance.DisplayMessage("Mapper", "node.warning", PersistentUI.DisplayMessageType.BOTTOM);
            }
        }

        UpdateJSON();
    }
 public BeatmapActionParams(BeatmapActionContainer container)
 {
     notes      = container.notes;
     obstacles  = container.obstacles;
     events     = container.events;
     bpm        = container.bpm;
     selection  = container.selection;
     nodeEditor = container.nodeEditor;
 }
Esempio n. 6
0
    private IEnumerator GenerateStrobeCoroutine(int valueA, int valueB, bool regular, bool chroma, bool dynamic, bool swapColors, int interval, int chromaOffset)
    {
        generatedObjects.Clear();
        //yield return PersistentUI.Instance.FadeInLoadingScreen();
        List <BeatmapEventContainer> containers         = SelectionController.SelectedObjects.Where(x => x is BeatmapEventContainer).Cast <BeatmapEventContainer>().ToList(); //Grab selected objects
        List <BeatmapObject>         conflictingObjects = new List <BeatmapObject>();                                                                                         //For the Action

        //Order by type, then by descending time
        containers = containers.OrderBy(x => x.eventData._type).ThenByDescending(x => x.eventData._time).ToList();
        for (var i = 0; i < 15; i++)
        {
            if (containers.Count(x => (x.objectData as MapEvent)._type == i) >= 2)
            {
                List <BeatmapEventContainer> filteredContainers = containers.Where(x => x.eventData._type == i).ToList();
                BeatmapEventContainer        end   = filteredContainers.First();
                BeatmapEventContainer        start = filteredContainers.Last();

                List <BeatmapEventContainer> containersBetween = eventsContainer.LoadedContainers.Where(x =>
                                                                                                        (x.objectData as MapEvent)._type == i && //Grab all events between start and end point.
                                                                                                        x.objectData._time >= start.objectData._time && x.objectData._time <= end.objectData._time
                                                                                                        ).OrderBy(x => x.objectData._time).Cast <BeatmapEventContainer>().ToList();

                List <MapEvent> regularEventData = containersBetween.Select(x => x.eventData).Where(x => x._value < ColourManager.RGB_INT_OFFSET).ToList();

                List <MapEvent> chromaEvents = new List <MapEvent>()
                {
                    FindAttachedChromaEvent(start)?.eventData
                };
                chromaEvents.AddRange(containersBetween.Where(x => x.eventData._value >= ColourManager.RGB_INT_OFFSET).Select(x => x.eventData));
                chromaEvents = chromaEvents.Where(x => x != null).DistinctBy(x => x._time).ToList();

                conflictingObjects.AddRange(chromaEvents.Concat(regularEventData));

                foreach (BeatmapEventContainer e in containersBetween)
                {
                    eventsContainer.DeleteObject(e);
                }

                if (regular)
                {
                    yield return(StartCoroutine(GenerateRegularStrobe(i, valueA, valueB, end.eventData._time, start.eventData._time, swapColors, dynamic, interval, regularEventData)));
                }
                if (chroma && chromaEvents.Count > 0)
                {
                    yield return(StartCoroutine(GenerateChromaStrobe(i, end.eventData._time, start.eventData._time, interval, 1f / chromaOffset, chromaEvents)));
                }
            }
        }
        generatedObjects.OrderBy(x => x.objectData._time);
        SelectionController.RefreshMap();
        //yield return PersistentUI.Instance.FadeOutLoadingScreen();
        SelectionController.DeselectAll();
        SelectionController.SelectedObjects.AddRange(generatedObjects);
        SelectionController.RefreshSelectionMaterial(false);
        BeatmapActionContainer.AddAction(new StrobeGeneratorGenerationAction(generatedObjects, conflictingObjects));
        generatedObjects.Clear();
    }
Esempio n. 7
0
 internal virtual void ApplyToMap()
 {
     objectData       = queuedData;
     objectData._time = RoundedTime;
     //objectContainerCollection.RemoveConflictingObjects(new[] { objectData }, out List<BeatmapObject> conflicting);
     objectContainerCollection.SpawnObject(objectData, out List <BeatmapObject> conflicting);
     BeatmapActionContainer.AddAction(GenerateAction(objectData, conflicting));
     queuedData = BeatmapObject.GenerateCopy(queuedData);
 }
Esempio n. 8
0
        public IEnumerator LoadMap()
        {
            yield return(TestUtils.LoadMapper());

            _actionContainer = Object.FindObjectOfType <BeatmapActionContainer>();
            _mirror          = Object.FindObjectOfType <MirrorSelection>();
            _notesContainer  = BeatmapObjectContainerCollection.GetCollectionForType(BeatmapObject.Type.NOTE);
            _root            = _notesContainer.transform.root;
            _notePlacement   = _root.GetComponentInChildren <NotePlacement>();
        }
Esempio n. 9
0
    public void ToggleHyperWall(BeatmapObstacleContainer obs)
    {
        if (BeatmapObject.GenerateCopy(obs.objectData) is BeatmapObstacle edited)
        {
            edited._time     += obs.obstacleData._duration;
            edited._duration *= -1f;

            BeatmapActionContainer.AddAction(new BeatmapObjectModifiedAction(edited, obs.objectData, obs.objectData), true);
        }
    }
Esempio n. 10
0
 public void DeleteObject(BeatmapObjectContainer obj)
 {
     if (LoadedContainers.Contains(obj))
     {
         BeatmapActionContainer.AddAction(new BeatmapObjectDeletionAction(obj));
         LoadedContainers.Remove(obj);
         Destroy(obj.gameObject);
         SelectionController.RefreshMap();
     }
 }
Esempio n. 11
0
    internal virtual void ApplyToMap()
    {
        objectData       = BeatmapObject.GenerateCopy(queuedData);
        objectData._time = RoundedTime;
        BOC spawned = objectContainerCollection.SpawnObject(objectData, out BeatmapObjectContainer conflicting) as BOC;

        BeatmapActionContainer.AddAction(GenerateAction(spawned, conflicting));
        SelectionController.RefreshMap();
        queuedData = BeatmapObject.GenerateCopy(queuedData);
    }
Esempio n. 12
0
    public void NodeEditor_EndEdit(string nodeText)
    {
        CMInputCallbackInstaller.ClearDisabledActionMaps(typeof(NodeEditorController), new[] { typeof(CMInput.INodeEditorActions) });
        CMInputCallbackInstaller.ClearDisabledActionMaps(typeof(NodeEditorController), actionMapsDisabled);

        try
        {
            if (!isEditing || !IsActive)
            {
                return;
            }
            JSONNode newNode = JSON.Parse(nodeText);      //Parse JSON, and do some basic checks.
            if (string.IsNullOrEmpty(newNode.ToString())) //Damn you Jackz
            {
                throw new Exception("Node cannot be empty.");
            }

            // Super sneaky clone, maybe not needed
            var dict = editingObjects.ToDictionary(it => it, it => it.ConvertToJSON().Clone());

            ApplyJSON(editingNode.AsObject, newNode.AsObject, dict);

            var beatmapActions = dict.Select(entry =>
                                             new BeatmapObjectModifiedAction(
                                                 Activator.CreateInstance(entry.Key.GetType(), new object[] { entry.Value }) as BeatmapObject,
                                                 entry.Key, entry.Key, $"Edited a {entry.Key.beatmapType} with Node Editor.", true)
                                             ).ToList();

            BeatmapActionContainer.AddAction(new ActionCollectionAction(beatmapActions, true, true, $"Edited ({editingObjects.Count()}) objects with Node Editor."), true);
            UpdateJSON();
        }
        catch (Exception e)
        {
            string message = e.Message;
            switch (e)
            {
            case JSONParseException jsonParse:     // Error parsing input JSON; tell them what's wrong!
                message = jsonParse.ToUIFriendlyString();
                break;

            case TargetInvocationException invocationException:     // Error when converting JSON to an object; tell them what's wrong!
                message = invocationException.InnerException.Message;
                break;

            default:
                //Log the full error to the console
                Debug.LogError(e);
                break;
            }
            PersistentUI.Instance.ShowDialogBox(message, null, PersistentUI.DialogBoxPresetType.Ok);
        }
    }
Esempio n. 13
0
    private void FinishDrag()
    {
        if (!(isDraggingObject || isDraggingObjectAtTime))
        {
            return;
        }
        //First, find and delete anything that's overlapping our dragged object.
        var selected = SelectionController.IsObjectSelected(draggedObjectData);

        // To delete properly we need to set the original time
        float _time = draggedObjectData._time;

        draggedObjectData._time = originalDraggedObjectData._time;
        objectContainerCollection.DeleteObject(draggedObjectData, false, false);
        draggedObjectData._time = _time;

        objectContainerCollection.SpawnObject(draggedObjectData, out List <BeatmapObject> conflicting, true, true);
        if (conflicting.Contains(draggedObjectData))
        {
            conflicting.Remove(draggedObjectData);

            if (selected)
            {
                SelectionController.Select(draggedObjectData);
            }
        }

        queuedData = BeatmapObject.GenerateCopy(originalQueued);
        BeatmapAction action;

        // Don't queue an action if we didn't actually change anything
        if (draggedObjectData.ToString() != originalDraggedObjectData.ToString())
        {
            if (conflicting.Any())
            {
                action = new BeatmapObjectModifiedWithConflictingAction(draggedObjectData, draggedObjectData, originalDraggedObjectData, conflicting.First(), "Modified via alt-click and drag.");
            }
            else
            {
                action = new BeatmapObjectModifiedAction(draggedObjectData, draggedObjectData, originalDraggedObjectData, "Modified via alt-click and drag.");
            }
            BeatmapActionContainer.AddAction(action);
        }

        draggedObjectContainer.dragging = false;
        draggedObjectContainer          = null;
        ClickAndDragFinished();
        isDraggingObject = isDraggingObjectAtTime = false;
    }
Esempio n. 14
0
    /// <summary>
    /// Deletes and clears the current selection.
    /// </summary>
    public void Delete(bool triggersAction = true)
    {
        IEnumerable <BeatmapObject> objects = SelectedObjects.ToArray();

        if (triggersAction)
        {
            BeatmapActionContainer.AddAction(new SelectionDeletedAction(objects));
        }
        DeselectAll();
        foreach (BeatmapObject con in objects)
        {
            BeatmapObjectContainerCollection.GetCollectionForType(con.beatmapType).DeleteObject(con, false, false);
        }
        BeatmapObjectContainerCollection.RefreshAllPools();
    }