예제 #1
0
 internal override void ApplyToMap()
 {
     if (IsPlacing)
     {
         IsPlacing            = false;
         queuedData._time     = startTime;
         queuedData._duration = instantiatedContainer.transform.localScale.z / EditorScaleController.EditorScale;
         if (queuedData._duration < smallestRankableWallDuration && Settings.Instance.DontPlacePerfectZeroDurationWalls)
         {
             queuedData._duration = smallestRankableWallDuration;
         }
         objectContainerCollection.SpawnObject(queuedData, out List <BeatmapObject> conflicting);
         BeatmapActionContainer.AddAction(GenerateAction(queuedData, conflicting));
         queuedData = GenerateOriginalData();
         instantiatedContainer.obstacleData = queuedData;
         obstacleAppearanceSO.SetObstacleAppearance(instantiatedContainer);
         instantiatedContainer.transform.localScale = new Vector3(
             1, instantiatedContainer.transform.localPosition.y == 0 ? 3.5f : 2, 0);
     }
     else
     {
         IsPlacing   = true;
         originIndex = queuedData._lineIndex;
         startTime   = RoundedTime;
     }
 }
예제 #2
0
    /// <summary>
    /// Pastes any copied objects into the map, selecting them immediately.
    /// </summary>
    public void Paste(bool triggersAction = true)
    {
        DeselectAll();
        CopiedObjects = CopiedObjects.OrderBy((x) => x._time).ToList();
        List <BeatmapObjectContainer> pasted = new List <BeatmapObjectContainer>();

        foreach (BeatmapObject data in CopiedObjects)
        {
            if (data == null)
            {
                continue;
            }
            float         newTime = data._time + atsc.CurrentBeat;
            BeatmapObject newData = BeatmapObject.GenerateCopy(data);
            newData._time = newTime;
            BeatmapObjectContainer pastedContainer = collections.Where(x => x.ContainerType == newData.beatmapType).FirstOrDefault()?.SpawnObject(newData, out _);
            pasted.Add(pastedContainer);
        }
        if (triggersAction)
        {
            BeatmapActionContainer.AddAction(new SelectionPastedAction(pasted, CopiedObjects, atsc.CurrentBeat));
        }
        foreach (BeatmapObjectContainer obj in pasted)
        {
            Select(obj, true, false);
        }
        RefreshSelectionMaterial(false);
        RefreshMap();
        Debug.Log("Pasted!");
    }
예제 #3
0
    public void Paint()
    {
        List <BeatmapAction> allActions = new List <BeatmapAction>();

        foreach (var obj in SelectionController.SelectedObjects)
        {
            if (obj is BeatmapBPMChange || obj is BeatmapCustomEvent)
            {
                continue;                                                       //These should probably not be colored.
            }
            var beforePaint = BeatmapObject.GenerateCopy(obj);
            if (DoPaint(obj))
            {
                allActions.Add(new BeatmapObjectModifiedAction(obj, obj, beforePaint, "a", true));
            }
        }

        if (allActions.Count == 0)
        {
            return;
        }

        foreach (var unique in SelectionController.SelectedObjects.DistinctBy(x => x.beatmapType))
        {
            BeatmapObjectContainerCollection.GetCollectionForType(unique.beatmapType).RefreshPool(true);
        }

        BeatmapActionContainer.AddAction(new ActionCollectionAction(allActions, true, true, "Painted a selection of objects."));
    }
예제 #4
0
    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();
    }
예제 #5
0
    internal override void ApplyToMap()
    {
        queuedData._time = (instantiatedContainer.transform.position.z / EditorScaleController.EditorScale)
                           + atsc.CurrentBeat;
        if ((KeybindsController.AltHeld || (Settings.Instance.PlaceOnlyChromaEvents && Settings.Instance.PlaceChromaEvents)) && !queuedData.IsUtilityEvent()) // no more laser speed events gone wack
        {
            MapEvent justChroma = BeatmapObject.GenerateCopy(queuedData);
            justChroma._value = ColourManager.ColourToInt(colorPicker.CurrentColor);
            BeatmapEventContainer container = objectContainerCollection.SpawnObject(justChroma) as BeatmapEventContainer;
            BeatmapActionContainer.AddAction(new BeatmapEventPlacementAction(container, null));
            SelectionController.RefreshMap();
            queuedData = BeatmapObject.GenerateCopy(queuedData);
            return;
        }
        BeatmapEventContainer spawned = objectContainerCollection.SpawnObject(BeatmapObject.GenerateCopy(queuedData)) as BeatmapEventContainer;
        BeatmapEventContainer chroma  = null;

        if (Settings.Instance.PlaceChromaEvents && !queuedData.IsUtilityEvent() && (queuedValue != MapEvent.LIGHT_VALUE_OFF)) // off events arent affected by chroma blocks, no need to create extra ones
        {
            MapEvent chromaData = BeatmapObject.GenerateCopy(queuedData);
            chromaData._time -= 1 / 64f;
            chromaData._value = ColourManager.ColourToInt(colorPicker.CurrentColor);
            chroma            = objectContainerCollection.SpawnObject(chromaData) as BeatmapEventContainer;
        }
        BeatmapActionContainer.AddAction(new BeatmapEventPlacementAction(spawned, chroma));
        SelectionController.RefreshMap();
        queuedData = BeatmapObject.GenerateCopy(queuedData);
    }
    internal override void ApplyToMap()
    {
        if (isPlacing)
        {
            isPlacing            = false;
            queuedData._time     = startTime;
            queuedData._duration = instantiatedContainer.transform.localScale.z / EditorScaleController.EditorScale;
            if (queuedData._duration == 0 && Settings.Instance.DontPlacePerfectZeroDurationWalls)
            {
                queuedData._duration = 0.01f;
            }
            BeatmapObstacleContainer spawned = objectContainerCollection.SpawnObject(queuedData, out BeatmapObjectContainer conflicting) as BeatmapObstacleContainer;
            BeatmapActionContainer.AddAction(GenerateAction(spawned, conflicting));
            queuedData = GenerateOriginalData();
            instantiatedContainer.obstacleData = queuedData;
            obstacleAppearanceSO.SetObstacleAppearance(instantiatedContainer);
            instantiatedContainer.transform.localScale = new Vector3(
                1, instantiatedContainer.transform.localPosition.y == 0 ? 3.5f : 2, 0);

            Vector3 localRotation = spawned.transform.localEulerAngles;
            Track   track         = tracksManager.CreateTrack(gridRotation.Rotation);
            track.AttachContainer(spawned);
            tracksManager?.RefreshTracks();

            spawned.UpdateGridPosition();
            spawned.transform.localEulerAngles = localRotation;
        }
        else
        {
            isPlacing   = true;
            originIndex = queuedData._lineIndex;
            startTime   = RoundedTime;
        }
    }
예제 #7
0
    /// <summary>
    /// Pastes any copied objects into the map, selecting them immediately.
    /// </summary>
    public void Paste(bool triggersAction = true)
    {
        DeselectAll();
        CopiedObjects = new HashSet <BeatmapObject>(CopiedObjects.OrderBy(x => x._time));
        HashSet <BeatmapObjectContainer> pasted = new HashSet <BeatmapObjectContainer>();

        foreach (BeatmapObject data in CopiedObjects)
        {
            if (data == null)
            {
                continue;
            }
            float         newTime = data._time + atsc.CurrentBeat;
            BeatmapObject newData = BeatmapObject.GenerateCopy(data);
            newData._time = newTime;
            BeatmapObjectContainer pastedContainer = collections.Where(x => x.ContainerType == newData.beatmapType).FirstOrDefault()?.SpawnObject(newData, out _);
            pastedContainer.UpdateGridPosition();
            Select(pastedContainer, true, false, false);
            pasted.Add(pastedContainer);
        }
        if (triggersAction)
        {
            BeatmapActionContainer.AddAction(new SelectionPastedAction(pasted, CopiedObjects, atsc.CurrentBeat));
        }
        RefreshSelectionMaterial(false);
        RefreshMap();
        tracksManager.RefreshTracks();

        if (eventPlacement.objectContainerCollection.RingPropagationEditing)
        {
            eventPlacement.objectContainerCollection.RingPropagationEditing = eventPlacement.objectContainerCollection.RingPropagationEditing;
        }
        Debug.Log("Pasted!");
    }
    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));
    }
예제 #9
0
    public void NodeEditor_EndEdit(string nodeText)
    {
        CMInputCallbackInstaller.ClearDisabledActionMaps(new[] { typeof(CMInput.INodeEditorActions) });
        try
        {
            if (!isEditing || !IsActive || SelectionController.SelectedObjects.Count != 1)
            {
                return;
            }
            JSONNode newNode = JSON.Parse(nodeText);      //Parse JSON, and do some basic checks.
            if (string.IsNullOrEmpty(newNode.ToString())) //Damn you Jackz
            {
                throw new Exception("Invalid JSON!\n\nCheck to make sure the node is not empty.");
            }
            if (string.IsNullOrEmpty(newNode["_time"]))
            {
                throw new Exception("Invalid JSON!\n\nEvery object needs a \"_time\" value!");
            }

            //From this point on, its the mappers fault for whatever shit happens from JSON.

            BeatmapObject original = BeatmapObject.GenerateCopy(editingContainer.objectData);
            editingContainer.objectData = Activator.CreateInstance(editingContainer.objectData.GetType(), new object[] { newNode }) as BeatmapObject;
            BeatmapActionContainer.AddAction(new NodeEditorUpdatedNodeAction(editingContainer, editingContainer.objectData, original));
            UpdateAppearance(editingContainer);
            isEditing = false;
        }
        catch (Exception e) { PersistentUI.Instance.ShowDialogBox(e.Message, null, PersistentUI.DialogBoxPresetType.Ok); }
    }
    /// <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})");
        }
    }
예제 #11
0
 internal override void ApplyToMap()
 {
     if (isPlacing)
     {
         isPlacing            = false;
         queuedData._time     = startTime;
         queuedData._duration = instantiatedContainer.transform.localScale.z / EditorScaleController.EditorScale;
         if (queuedData._duration == 0 && Settings.Instance.DontPlacePerfectZeroDurationWalls)
         {
             queuedData._duration = 0.01f;
         }
         BeatmapObstacleContainer spawned = objectContainerCollection.SpawnObject(queuedData, out BeatmapObjectContainer conflicting) as BeatmapObstacleContainer;
         BeatmapActionContainer.AddAction(GenerateAction(spawned, conflicting));
         SelectionController.RefreshMap();
         queuedData = GenerateOriginalData();
         instantiatedContainer.obstacleData = queuedData;
         obstacleAppearanceSO.SetObstacleAppearance(instantiatedContainer);
         instantiatedContainer.transform.localScale = new Vector3(
             1, instantiatedContainer.transform.position.y == 0 ? 3.5f : 2, 0);
     }
     else
     {
         isPlacing   = true;
         originIndex = queuedData._lineIndex;
         startTime   = RoundedTime;
     }
 }
예제 #12
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();
    }
예제 #13
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);
 }
예제 #14
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);
        }
    }
예제 #15
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);
    }
예제 #16
0
    public void UpdateNoteDirection(BeatmapNoteContainer note, bool shiftForward)
    {
        var original = BeatmapObject.GenerateCopy(note.objectData);

        note.mapNoteData._cutDirection  = (shiftForward ? CutDirectionMovedForward : CutDirectionMovedBackward)[note.mapNoteData._cutDirection];
        note.transform.localEulerAngles = BeatmapNoteContainer.Directionalize(note.mapNoteData);
        BeatmapObjectContainerCollection.GetCollectionForType <NotesContainer>(BeatmapObject.Type.NOTE)
        .RefreshSpecialAngles(note.objectData, false, false);
        BeatmapActionContainer.AddAction(new BeatmapObjectModifiedAction(note.objectData, note.objectData, original));
    }
예제 #17
0
 public void DeleteObject(BeatmapObjectContainer obj)
 {
     if (LoadedContainers.Contains(obj))
     {
         BeatmapActionContainer.AddAction(new BeatmapObjectDeletionAction(obj));
         LoadedContainers.Remove(obj);
         Destroy(obj.gameObject);
         SelectionController.RefreshMap();
     }
 }
예제 #18
0
    internal virtual void ApplyToMap()
    {
        objectData       = BeatmapObject.GenerateCopy(queuedData);
        objectData._time = (instantiatedContainer.transform.position.z / EditorScaleController.EditorScale)
                           + atsc.CurrentBeat;
        BOC spawned = objectContainerCollection.SpawnObject(objectData) as BOC;

        BeatmapActionContainer.AddAction(GenerateAction(spawned));
        SelectionController.RefreshMap();
        queuedData = BeatmapObject.GenerateCopy(queuedData);
    }
예제 #19
0
 /// <summary>
 /// Can be very taxing. Use sparringly.
 /// </summary>
 internal static void RefreshSelectionMaterial(bool triggersAction = true)
 {
     SelectedObjects.RemoveAll(x => x == null);
     foreach (BeatmapObjectContainer con in SelectedObjects)
     {
         con.SetOutlineColor(instance.selectedColor);
     }
     if (triggersAction)
     {
         BeatmapActionContainer.AddAction(new SelectionChangedAction(SelectedObjects));
     }
 }
예제 #20
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);
        }
    }
예제 #21
0
 public void DeleteObject(BeatmapObjectContainer obj, bool triggersAction = true, string comment = "No comment.")
 {
     if (LoadedContainers.Contains(obj))
     {
         if (triggersAction)
         {
             BeatmapActionContainer.AddAction(new BeatmapObjectDeletionAction(obj, comment));
         }
         LoadedContainers.Remove(obj);
         Destroy(obj.gameObject);
         SelectionController.RefreshMap();
     }
 }
예제 #22
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;
    }
예제 #23
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();
    }
예제 #24
0
 /// <summary>
 /// Deletes and clears the current selection.
 /// </summary>
 public void Delete(bool triggersAction = true)
 {
     if (triggersAction)
     {
         BeatmapActionContainer.AddAction(new SelectionDeletedAction(SelectedObjects));
     }
     foreach (BeatmapObjectContainer con in SelectedObjects)
     {
         foreach (BeatmapObjectContainerCollection container in collections)
         {
             container.DeleteObject(con);
         }
     }
     SelectedObjects.Clear();
     RefreshMap();
 }
예제 #25
0
    /// <summary>
    /// Pastes any copied objects into the map, selecting them immediately.
    /// </summary>
    public void Paste(bool triggersAction = true)
    {
        DeselectAll();
        CopiedObjects = CopiedObjects.OrderBy((x) => x._time).ToList();
        List <BeatmapObjectContainer> pasted = new List <BeatmapObjectContainer>();

        foreach (BeatmapObject data in CopiedObjects)
        {
            if (data == null)
            {
                continue;
            }
            float newTime = data._time + atsc.CurrentBeat;
            BeatmapObjectContainer pastedContainer = null;
            if (data is BeatmapNote)
            {
                BeatmapObject newData = new BeatmapNote(data.ConvertToJSON());
                newData._time = newTime;
                NotesContainer notes = collections.Where(x => x is NotesContainer).FirstOrDefault() as NotesContainer;
                pastedContainer = notes?.SpawnObject(newData);
            }
            if (data is BeatmapObstacle)
            {
                BeatmapObject newData = new BeatmapObstacle(data.ConvertToJSON());
                newData._time = newTime;
                ObstaclesContainer obstacles = collections.Where(x => x is ObstaclesContainer).FirstOrDefault() as ObstaclesContainer;
                pastedContainer = obstacles?.SpawnObject(newData);
            }
            if (data is MapEvent)
            {
                BeatmapObject newData = new MapEvent(data.ConvertToJSON());
                newData._time = newTime;
                EventsContainer events = collections.Where(x => x is EventsContainer).FirstOrDefault() as EventsContainer;
                pastedContainer = events?.SpawnObject(newData);
            }
            pasted.Add(pastedContainer);
        }
        if (triggersAction)
        {
            BeatmapActionContainer.AddAction(new SelectionPastedAction(pasted, CopiedObjects, atsc.CurrentBeat));
        }
        SelectedObjects.AddRange(pasted);
        RefreshSelectionMaterial(false);
        RefreshMap();
        Debug.Log("Pasted!");
    }
예제 #26
0
 public void OnChangeWallDuration(InputAction.CallbackContext context)
 {
     if (customStandaloneInputModule.IsPointerOverGameObject <GraphicRaycaster>(-1, true))
     {
         return;
     }
     RaycastFirstObject(out BeatmapObstacleContainer obs);
     if (obs != null && !obs.dragging && context.performed)
     {
         BeatmapObject original = BeatmapObject.GenerateCopy(obs.objectData);
         float         snapping = 1f / atsc.gridMeasureSnapping;
         snapping *= context.ReadValue <float>() > 0 ? 1 : -1;
         obs.obstacleData._duration += snapping;
         obs.UpdateGridPosition();
         obstacleAppearanceSO.SetObstacleAppearance(obs);
         BeatmapActionContainer.AddAction(new BeatmapObjectModifiedAction(obs.objectData, obs.objectData, original));
     }
 }
예제 #27
0
    public void InvertNote(BeatmapNoteContainer note)
    {
        if (note.mapNoteData._type == BeatmapNote.NOTE_TYPE_BOMB)
        {
            return;
        }

        var original = BeatmapObject.GenerateCopy(note.objectData);
        var newType  = note.mapNoteData._type == BeatmapNote.NOTE_TYPE_A ? BeatmapNote.NOTE_TYPE_B : BeatmapNote.NOTE_TYPE_A;

        note.mapNoteData._type = newType;
        noteAppearanceSO.SetNoteAppearance(note);
        var collection = BeatmapObjectContainerCollection.GetCollectionForType <NotesContainer>(BeatmapObject.Type.NOTE);

        collection.RefreshSpecialAngles(note.objectData, false, false);
        collection.RefreshSpecialAngles(original, false, false);
        BeatmapActionContainer.AddAction(new BeatmapObjectModifiedAction(note.objectData, note.objectData, original));
    }
    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));
        queuedData = BeatmapObject.GenerateCopy(queuedData);
        if (AssignTo360Tracks)
        {
            Vector3 localRotation = spawned.transform.localEulerAngles;
            Track   track         = tracksManager.GetTrackForRotationValue(gridRotation.Rotation);
            track?.AttachContainer(spawned);
            spawned.UpdateGridPosition();
            spawned.transform.localEulerAngles = localRotation;
            tracksManager.RefreshTracks();
        }
    }
예제 #29
0
    public IEnumerator GenerateStrobeCoroutine()
    {
        generatedObjects.Clear();
        if (atsc.gridMeasureSnapping >= 32)
        {
            PersistentUI.Instance.DisplayMessage("This could take a while!", PersistentUI.DisplayMessageType.BOTTOM);
        }
        //yield return PersistentUI.Instance.FadeInLoadingScreen();
        List <BeatmapObjectContainer> containers          = SelectionController.SelectedObjects;            //Grab selected objects
        List <BeatmapObjectContainer> notGeneratedObjects = new List <BeatmapObjectContainer>();            //For the Action

        containers = containers.Where((BeatmapObjectContainer x) => (x is BeatmapEventContainer)).ToList(); //Filter Event containers
        //Order by type, then by descending time
        containers = containers.OrderBy(x => (x.objectData as MapEvent)._type).ThenByDescending(x => x.objectData._time).ToList();
        for (var i = 0; i < 15; i++)
        {
            if (containers.Count(x => (x.objectData as MapEvent)._type == i) >= 2)
            {
                List <BeatmapObjectContainer> filteredContainers = containers.Where(x => (x.objectData as MapEvent)._type == i).ToList();
                BeatmapEventContainer         end               = filteredContainers.First() as BeatmapEventContainer;
                BeatmapEventContainer         start             = filteredContainers.Last() as BeatmapEventContainer;
                List <BeatmapObjectContainer> 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).ToList();
                containersBetween.Add(FindAttachedChromaEvent(start)); //Add the first Chroma RGB event so gradients can work
                notGeneratedObjects.Add(filteredContainers.First());   //for the love of god please work
                notGeneratedObjects.AddRange(containersBetween);       //Add this to our list of objects that are here from the start.
                yield return(StartCoroutine(GenerateOneStrobe(start.eventData._type, eventPreview.queuedData._value,
                                                              end.objectData._time, start.objectData._time, containersBetween)));
            }
        }
        generatedObjects.OrderBy(x => x.objectData._time);
        generatedObjects.RemoveAll(x => notGeneratedObjects.Contains(x));
        SelectionController.RefreshMap();
        //yield return PersistentUI.Instance.FadeOutLoadingScreen();
        SelectionController.DeselectAll();
        SelectionController.SelectedObjects.AddRange(generatedObjects);
        SelectionController.SelectedObjects.AddRange(notGeneratedObjects);
        SelectionController.RefreshSelectionMaterial(false);
        BeatmapActionContainer.AddAction(new StrobeGeneratorGenerationAction(generatedObjects, notGeneratedObjects));
        generatedObjects.Clear();
    }
예제 #30
0
    internal override void ApplyToMap()
    {
        queuedData._time = RoundedTime;
        if ((KeybindsController.AltHeld || (Settings.Instance.PlaceOnlyChromaEvents && Settings.Instance.PlaceChromaEvents)) && !queuedData.IsUtilityEvent())
        {
            MapEvent justChroma = BeatmapObject.GenerateCopy(queuedData);
            justChroma._value = ColourManager.ColourToInt(colorPicker.CurrentColor);
            BeatmapEventContainer container = objectContainerCollection.SpawnObject(justChroma, out BeatmapObjectContainer conflicting2) as BeatmapEventContainer;
            BeatmapActionContainer.AddAction(new BeatmapObjectPlacementAction(new List <BeatmapObjectContainer>()
            {
                conflicting2
            },
                                                                              new List <BeatmapObjectContainer>()
            {
                container
            }));
            SelectionController.RefreshMap();
            queuedData = BeatmapObject.GenerateCopy(queuedData);
            return;
        }
        BeatmapEventContainer spawned = objectContainerCollection.SpawnObject(BeatmapObject.GenerateCopy(queuedData), out BeatmapObjectContainer conflicting) as BeatmapEventContainer;
        BeatmapEventContainer chroma  = null;

        if (Settings.Instance.PlaceChromaEvents && !queuedData.IsUtilityEvent() && (queuedValue != MapEvent.LIGHT_VALUE_OFF))
        {
            MapEvent chromaData = BeatmapObject.GenerateCopy(queuedData);
            chromaData._time -= 1 / 64f;
            chromaData._value = ColourManager.ColourToInt(colorPicker.CurrentColor);
            chroma            = objectContainerCollection.SpawnObject(chromaData, out _) as BeatmapEventContainer;
        }
        BeatmapActionContainer.AddAction(new BeatmapObjectPlacementAction(new List <BeatmapObjectContainer>()
        {
            conflicting
        },
                                                                          new List <BeatmapObjectContainer>()
        {
            spawned, chroma
        }));
        SelectionController.RefreshMap();
        queuedData = BeatmapObject.GenerateCopy(queuedData);
    }