internal override void ApplyToMap() { if (!IsSelecting) { IsSelecting = true; startTime = RoundedTime; } else { StartCoroutine(WaitABitFuckOffOtherPlacementControllers()); List <BeatmapObjectContainer> toSelect = new List <BeatmapObjectContainer>(); //Big brain boye does big brain things with big brain box BoxCollider boxyBoy = instantiatedContainer.GetComponent <BoxCollider>(); Collider[] boxyBoyHitsStuffTM = Physics.OverlapBox(boxyBoy.bounds.center, boxyBoy.bounds.extents, boxyBoy.transform.rotation, 1 << 9); foreach (Collider collider in boxyBoyHitsStuffTM) { BeatmapObjectContainer containerBoye = collider.gameObject.GetComponent <BeatmapObjectContainer>(); if (containerBoye != null) { toSelect.Add(containerBoye); } } if (!KeybindsController.ShiftHeld) { SelectionController.DeselectAll(); } foreach (BeatmapObjectContainer obj in toSelect) { SelectionController.Select(obj, true, false); } SelectionController.RefreshSelectionMaterial(toSelect.Any()); } }
public override void Redo(BeatmapActionContainer.BeatmapActionParams param) { oldSelected = new HashSet <BeatmapObjectContainer>(SelectionController.SelectedObjects); SelectionController.DeselectAll(); SelectionController.SelectedObjects = new HashSet <BeatmapObjectContainer>(selected); SelectionController.RefreshSelectionMaterial(false); }
public override void Undo(BeatmapActionContainer.BeatmapActionParams param) { selected = new List <BeatmapObjectContainer>(SelectionController.SelectedObjects); SelectionController.DeselectAll(); SelectionController.SelectedObjects.AddRange(oldSelected); SelectionController.RefreshSelectionMaterial(false); }
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(); }
public void _on_Clickable_input_event(Godot.Object viewport, InputEvent @event, int shapeIdx) { if (Input.IsActionJustPressed("click")) { parentNode.Visible = false; SelectionController.DeselectAll(); //ProjectSettings.SetSetting("physics/common/enable_object_picking", false); } }
void SelectionKeybinds() { if (NodeEditorController.IsActive) { return; } if (Input.GetKeyDown(KeyCode.Delete) || (ShiftHeld && Input.GetMouseButtonDown(2))) { sc.Delete(); } if (CtrlHeld) { if (Input.GetKeyDown(KeyCode.A)) { SelectionController.DeselectAll(); } if (Input.GetKeyDown(KeyCode.C)) { sc.Copy(); } if (Input.GetKeyDown(KeyCode.X)) { sc.Copy(true); } } if (ShiftHeld) { if (Input.GetKeyDown(KeyCode.UpArrow)) { sc.MoveSelection(1f / atsc.gridMeasureSnapping); } else if (Input.GetKeyDown(KeyCode.DownArrow)) { sc.MoveSelection(-1f / atsc.gridMeasureSnapping); } } else { if (Input.GetKeyDown(KeyCode.LeftArrow)) { sc.ShiftSelection(-1, 0); } if (Input.GetKeyDown(KeyCode.RightArrow)) { sc.ShiftSelection(1, 0); } if (Input.GetKeyDown(KeyCode.UpArrow)) { sc.ShiftSelection(0, 1); } if (Input.GetKeyDown(KeyCode.DownArrow)) { sc.ShiftSelection(0, -1); } } }
private void Update() { UpdateTouchMode(); switch (ControlMode) { case Mode.CameraMovement: CamCtrl.UpdateCamera(); break; case Mode.Selecting: // 1) on hit => selecting mode // 2) else camera movement RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // | Input.GetTouch(0).position if (Physics.Raycast(ray, out hit)) { if (_currentSelected == null) { _currentSelected = hit.transform.gameObject; SelCtrl.ToggleAddToList(_currentSelected); } } else { _currentSelected = null; // move camera if nothing has been selected at first touch if (SelCtrl.Selected.IsEmpty()) { ControlMode = Mode.CameraMovement; CamCtrl.UpdateCamera(); } } break; case Mode.Idle: default: if (_currentSelected != null) { SelCtrl.FinalTarget(_currentSelected); _currentSelected = null; } else { SelCtrl.DeselectAll(); } break; } }
public override void Redo(BeatmapActionContainer.BeatmapActionParams param) { SelectionController.DeselectAll(); foreach (BeatmapObject obj in Data) { BeatmapObjectContainerCollection.GetCollectionForType(obj.beatmapType).SpawnObject(obj, false, false); SelectionController.Select(obj, true, false, false); } foreach (BeatmapObject obj in removed) { BeatmapObjectContainerCollection.GetCollectionForType(obj.beatmapType).DeleteObject(obj, false); } RefreshPools(Data); }
public override void Undo(BeatmapActionContainer.BeatmapActionParams param) { if (clearSelection) { SelectionController.DeselectAll(); } foreach (BeatmapAction action in actions) { action.Undo(param); } if (forceRefreshesPool) { RefreshPools(Data); } }
public override void Redo(BeatmapActionContainer.BeatmapActionParams param) { SelectionController.DeselectAll(); foreach (BeatmapObjectContainer obj in conflictingContainers) { BeatmapObjectContainerCollection.GetCollectionForType(obj.objectData.beatmapType).DeleteObject(obj, false); } foreach (BeatmapObject obj in data) { containers.Add(BeatmapObjectContainerCollection.GetCollectionForType(BeatmapObject.Type.EVENT)?.SpawnObject(BeatmapObject.GenerateCopy(obj), out _)); } foreach (BeatmapObjectContainer obj in containers) { SelectionController.Select(obj, true, false); } SelectionController.RefreshSelectionMaterial(false); param.tracksManager.RefreshTracks(); }
public override void Redo(BeatmapActionContainer.BeatmapActionParams param) { SelectionController.DeselectAll(); foreach (BeatmapObjectContainer obj in conflictingContainers) { param.collections.ForEach(x => x.DeleteObject(obj)); } foreach (BeatmapObject obj in data) { containers.Add(param.collections.Where(x => x.ContainerType == BeatmapObject.Type.EVENT).First().SpawnObject( BeatmapObject.GenerateCopy(obj), out _)); } foreach (BeatmapObjectContainer obj in containers) { SelectionController.Select(obj, true, false); } SelectionController.RefreshSelectionMaterial(false); }
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(); }
public void CompositeTest() { var actionContainer = Object.FindObjectOfType <BeatmapActionContainer>(); var notesContainer = BeatmapObjectContainerCollection.GetCollectionForType(BeatmapObject.Type.NOTE); var root = notesContainer.transform.root; var selectionController = root.GetComponentInChildren <SelectionController>(); var notePlacement = root.GetComponentInChildren <NotePlacement>(); var noteA = new BeatmapNote { _time = 2, _type = BeatmapNote.NOTE_TYPE_A }; var noteB = new BeatmapNote { _time = 2, _type = BeatmapNote.NOTE_TYPE_B, _lineIndex = 1, _lineLayer = 1 }; notePlacement.queuedData = noteA; notePlacement.RoundedTime = notePlacement.queuedData._time; notePlacement.ApplyToMap(); SelectionController.Select(noteA); selectionController.ShiftSelection(1, 1); // Should conflict with existing note and delete it notePlacement.queuedData = noteB; notePlacement.RoundedTime = notePlacement.queuedData._time; notePlacement.ApplyToMap(); SelectionController.Select(noteB); selectionController.ShiftSelection(1, 1); selectionController.Copy(true); selectionController.Paste(); selectionController.Delete(); void CheckState(int loadedObjects, int selectedObjects, int time, int type, int index, int layer) { Assert.AreEqual(loadedObjects, notesContainer.LoadedObjects.Count); Assert.AreEqual(selectedObjects, SelectionController.SelectedObjects.Count); Assert.AreEqual(time, notesContainer.UnsortedObjects[0]._time); Assert.AreEqual(type, ((BeatmapNote)notesContainer.UnsortedObjects[0])._type); Assert.AreEqual(index, ((BeatmapNote)notesContainer.UnsortedObjects[0])._lineIndex); Assert.AreEqual(layer, ((BeatmapNote)notesContainer.UnsortedObjects[0])._lineLayer); } // No notes loaded Assert.AreEqual(0, notesContainer.LoadedObjects.Count); Assert.AreEqual(0, notesContainer.UnsortedObjects.Count); // Undo delete action actionContainer.Undo(); CheckState(1, 1, 0, BeatmapNote.NOTE_TYPE_B, 2, 2); // Undo paste action actionContainer.Undo(); Assert.AreEqual(0, notesContainer.LoadedObjects.Count); Assert.AreEqual(0, notesContainer.UnsortedObjects.Count); // Undo cut action actionContainer.Undo(); CheckState(1, 1, 2, BeatmapNote.NOTE_TYPE_B, 2, 2); // Undo movement actionContainer.Undo(); CheckState(1, 1, 2, BeatmapNote.NOTE_TYPE_B, 1, 1); // Undo overwrite actionContainer.Undo(); CheckState(1, 0, 2, BeatmapNote.NOTE_TYPE_A, 1, 1); // Undo movement actionContainer.Undo(); CheckState(1, 1, 2, BeatmapNote.NOTE_TYPE_A, 0, 0); // Undo placement actionContainer.Undo(); Assert.AreEqual(0, notesContainer.LoadedObjects.Count); Assert.AreEqual(0, SelectionController.SelectedObjects.Count); // Redo it all! - Selection is lost :( actionContainer.Redo(); CheckState(1, 0, 2, BeatmapNote.NOTE_TYPE_A, 0, 0); // Moving it selects it actionContainer.Redo(); CheckState(1, 1, 2, BeatmapNote.NOTE_TYPE_A, 1, 1); // Everything is backwards actionContainer.Redo(); CheckState(1, 0, 2, BeatmapNote.NOTE_TYPE_B, 1, 1); actionContainer.Redo(); CheckState(1, 1, 2, BeatmapNote.NOTE_TYPE_B, 2, 2); actionContainer.Redo(); Assert.AreEqual(0, notesContainer.LoadedObjects.Count); Assert.AreEqual(0, notesContainer.UnsortedObjects.Count); // Redo paste actionContainer.Redo(); CheckState(1, 1, 0, BeatmapNote.NOTE_TYPE_B, 2, 2); // Delete redo should still work even if our object isn't selected SelectionController.DeselectAll(); // Redo delete actionContainer.Redo(); Assert.AreEqual(0, notesContainer.LoadedObjects.Count); Assert.AreEqual(0, notesContainer.UnsortedObjects.Count); }
public void GenerateStrobe(IEnumerable <StrobeGeneratorPass> passes) { List <BeatmapObject> generatedObjects = new List <BeatmapObject>(); IEnumerable <MapEvent> containers = SelectionController.SelectedObjects.Where(x => x is MapEvent).Cast <MapEvent>(); //Grab selected objects List <BeatmapObject> oldEvents = new List <BeatmapObject>(); //For the Action //Order by type, then by descending time var groupings = containers.GroupBy(x => x._type); foreach (var group in groupings) { int type = group.Key; // Try and do this in one pass so we don't tank performance var partitioned = group.GroupBy(y => y.IsLightIdEvent ? EventsContainer.PropMode.Light : EventsContainer.PropMode.Off) .ToDictionary(z => z.Key, modeGroup => modeGroup.Key == EventsContainer.PropMode.Off ? modeGroup.GroupBy(y => 1) : modeGroup.GroupBy(y => y.LightId[0])); foreach (var mode in partitioned) { var propMode = mode.Key; var propGroups = mode.Value; foreach (var propGroup in propGroups) { var customData = propGroup.FirstOrDefault()?._customData; var lightIds = customData == null ? null : customData["_lightID"]; if (propGroup.Count() >= 2) { IEnumerable <MapEvent> ordered = propGroup.OrderByDescending(x => x._time); MapEvent end = ordered.First(); MapEvent start = ordered.Last(); IEnumerable <MapEvent> containersBetween = eventsContainer.LoadedObjects.GetViewBetween(start, end).Cast <MapEvent>().Where(x => x._type == start._type && //Grab all events between start and end point. // This check isn't perfect but I think it covers anything that could occur without manual mischief (propMode != EventsContainer.PropMode.Light || start.IsLightIdEvent == x.IsLightIdEvent && (!start.IsLightIdEvent || x.LightId.Contains(start.LightId[0]))) ); oldEvents.AddRange(containersBetween); foreach (StrobeGeneratorPass pass in passes) { IEnumerable <MapEvent> validEvents = containersBetween.Where(x => pass.IsEventValidForPass(x)); if (validEvents.Count() >= 2) { List <MapEvent> strobePassGenerated = pass.StrobePassForLane(validEvents.OrderBy(x => x._time), type, propMode, lightIds).ToList(); // REVIEW: Perhaps implement a "smart merge" to conflicting events, rather than outright removing those from previous passes // Now, what would a "smart merge" entail? I have no clue. generatedObjects.RemoveAll(x => strobePassGenerated.Any(y => y.IsConflictingWith(x))); generatedObjects.AddRange(strobePassGenerated); } } } } } } generatedObjects.OrderBy(x => x._time); if (generatedObjects.Count > 0) { //Delete conflicting vanilla events foreach (MapEvent e in oldEvents) { eventsContainer.DeleteObject(e, false, false); } //Spawn objects that were generated foreach (MapEvent data in generatedObjects) { eventsContainer.SpawnObject(data, false, false); } eventsContainer.RefreshPool(true); //yield return PersistentUI.Instance.FadeOutLoadingScreen(); SelectionController.DeselectAll(); SelectionController.SelectedObjects = new HashSet <BeatmapObject>(generatedObjects); SelectionController.SelectionChangedEvent?.Invoke(); SelectionController.RefreshSelectionMaterial(false); BeatmapActionContainer.AddAction(new StrobeGeneratorGenerationAction(generatedObjects.ToArray(), oldEvents.ToArray())); } }
public override void Undo(BeatmapActionContainer.BeatmapActionParams param) { SelectionController.DeselectAll(); SelectionController.SelectedObjects = new HashSet <BeatmapObject>(Data); SelectionController.RefreshSelectionMaterial(false); }