public Vector2?GetPosition(CreateEventTypeLabels labels, EventsContainer.PropMode mode, int prop) { if (IsLightIdEvent) { PropId = labels.LightIdsToPropId(_type, LightId) ?? -1; } if (mode == EventsContainer.PropMode.Off) { return(new Vector2( labels.EventTypeToLaneId(_type) + 0.5f, 0.5f )); } if (_type != prop) { return(null); } if (IsLightIdEvent) { var x = mode == EventsContainer.PropMode.Prop ? PropId : -1; if (x < 0) { x = LightId.Length > 0 ? labels.LightIDToEditor(_type, LightId[0]) : -1; } return(new Vector2( x + 1.5f, 0.5f )); } return(new Vector2( 0.5f, 0.5f )); }
public override IEnumerable <MapEvent> StrobePassForLane(IEnumerable <MapEvent> original, int type, EventsContainer.PropMode propMode, JSONNode propID) { List <MapEvent> generatedObjects = new List <MapEvent>(); IEnumerable <MapEvent> nonGradients = original.Where(x => x._lightGradient == null); for (int i = 0; i < nonGradients.Count() - 1; i++) { MapEvent currentChroma = nonGradients.ElementAt(i); MapEvent nextChroma = nonGradients.ElementAt(i + 1); MapEvent generated = BeatmapObject.GenerateCopy(currentChroma); generated._lightGradient = new MapEvent.ChromaGradient( currentChroma._customData["_color"], //Start color nextChroma._customData["_color"], //End color nextChroma._time - currentChroma._time, //Duration easing); //Duration generated._customData.Remove("_color"); generatedObjects.Add(generated); } generatedObjects.Add(BeatmapObject.GenerateCopy(original.Last())); return(generatedObjects); }
public override IEnumerable <MapEvent> StrobePassForLane(IEnumerable <MapEvent> original, int type, EventsContainer.PropMode propMode, JSONNode propID) { List <MapEvent> generatedObjects = new List <MapEvent>(); float startTime = original.First()._time; float endTime = original.Last()._time; float distanceInBeats = endTime - startTime; float originalDistance = distanceInBeats; MapEvent lastPassed = original.First(); MapEvent nextEvent = original.ElementAt(1); float lastSpeed = GetLaserSpeedFromEvent(lastPassed); float nextSpeed = GetLaserSpeedFromEvent(nextEvent); while (distanceInBeats >= 0) { MapEvent any = original.Where(x => x._time <= endTime - distanceInBeats).LastOrDefault(); if (lastPassed != any) { lastPassed = any; nextEvent = original.Where(x => x._time > lastPassed._time).FirstOrDefault(); lastSpeed = GetLaserSpeedFromEvent(lastPassed); if (nextEvent == null) { nextEvent = lastPassed; } nextSpeed = GetLaserSpeedFromEvent(nextEvent); } float newTime = originalDistance - distanceInBeats + startTime; float progress = Mathf.InverseLerp(lastPassed._time, nextEvent._time, newTime); var decimalPreciseSpeed = Math.Round(Mathf.Lerp(lastSpeed, nextSpeed, easingFunc(progress)), decimalPrecision); // This does not support negative numbers, however I do not believe there is a reason to support them in the first place var roundedPreciseSpeed = (int)Math.Max(1, Math.Round(decimalPreciseSpeed, MidpointRounding.AwayFromZero)); var data = new MapEvent(newTime, type, 1) { _customData = new JSONObject(), _value = roundedPreciseSpeed }; // Bit cheeky but hopefully a bit more readable if (Math.Abs(decimalPreciseSpeed - roundedPreciseSpeed) > 0.01f) { data._customData["_preciseSpeed"] = decimalPreciseSpeed; } if (overrideDirection) { switch (type) { case MapEvent.EVENT_TYPE_LEFT_LASERS_SPEED: data._customData["_direction"] = Convert.ToInt32(leftRotatesClockwise); break; case MapEvent.EVENT_TYPE_RIGHT_LASERS_SPEED: data._customData["_direction"] = Convert.ToInt32(rightRotatesClockwise); break; } } if (lockLaserRotation) { data._customData["_lockPosition"] = true; } generatedObjects.Add(data); distanceInBeats -= 1 / interval; } return(generatedObjects); }
/// <summary> /// Perform a strobe generator pass on any <see cref="MapEvent._type"/>. /// These are all new objects that will overwrite the original, so ensure that /// the original events are not present /// (Or, if they are, you create a copy of them.) /// </summary> /// <param name="original">The list of all valid events for this pass.</param> /// <returns>A new list of objects that will be created.</returns> public abstract IEnumerable <MapEvent> StrobePassForLane(IEnumerable <MapEvent> original, int type, EventsContainer.PropMode propMode, JSONNode propID);
public override IEnumerable <MapEvent> StrobePassForLane(IEnumerable <MapEvent> original, int type, EventsContainer.PropMode propMode, JSONNode propID) { List <MapEvent> generatedObjects = new List <MapEvent>(); float startTime = original.First()._time; float endTime = original.Last()._time; List <int> alternatingTypes = new List <int>(values); int typeIndex = 0; if (alternateColors) { for (int i = 0; i < values.Count(); i++) { alternatingTypes.Add(InvertColors(alternatingTypes[i])); } } float distanceInBeats = endTime - startTime; float originalDistance = distanceInBeats; MapEvent lastPassed = null; while (distanceInBeats >= 0) { if (typeIndex >= alternatingTypes.Count) { typeIndex = 0; } MapEvent any = original.Where(x => x._time <= endTime - distanceInBeats).LastOrDefault(); if (any != lastPassed && dynamic && (MapEvent.IsBlueEventFromValue(any._value) != MapEvent.IsBlueEventFromValue(alternatingTypes[typeIndex]))) { lastPassed = any; for (int i = 0; i < alternatingTypes.Count; i++) { alternatingTypes[i] = InvertColors(alternatingTypes[i]); } } int value = alternatingTypes[typeIndex]; float progress = (originalDistance - distanceInBeats) / originalDistance; float newTime = (easingFunc(progress) * originalDistance) + startTime; MapEvent data = new MapEvent(newTime, type, value); if (propMode != EventsContainer.PropMode.Off) { if (value != MapEvent.LIGHT_VALUE_BLUE_ON && value != MapEvent.LIGHT_VALUE_RED_ON && value != MapEvent.LIGHT_VALUE_OFF) { data._value = value < 5 ? MapEvent.LIGHT_VALUE_BLUE_ON : MapEvent.LIGHT_VALUE_RED_ON; } data._customData = new JSONObject(); data._customData.Add("_lightID", propID); } generatedObjects.Add(data); typeIndex++; if (distanceInBeats > 0 && (distanceInBeats -= 1 / precision) < -0.001f) { distanceInBeats = 0; } else if (distanceInBeats <= 0) { break; } } return(generatedObjects); }
public override IEnumerable <MapEvent> StrobePassForLane(IEnumerable <MapEvent> original, int type, EventsContainer.PropMode propMode, JSONNode propID) { List <MapEvent> generatedObjects = new List <MapEvent>(); float startTime = original.First()._time; float endTime = original.Last()._time; // Aggregate all colors points into a dictionary Dictionary <float, Color> colorPoints = new Dictionary <float, Color>(); foreach (MapEvent e in original) { // Might as well be fancy and add support for Chroma 2.0 gradients if (e._lightGradient != null) { colorPoints.Add(e._time, e._lightGradient.StartColor); colorPoints.Add(e._time + e._lightGradient.Duration, e._lightGradient.EndColor); } else if (e.IsChromaEvent) // This already checks customData, so if this is true then customData exists. { colorPoints.Add(e._time, e._customData["_color"]); } } float distanceInBeats = endTime - startTime; float originalDistance = distanceInBeats; if (colorPoints.Count < 2) { return(Enumerable.Empty <MapEvent>()); } KeyValuePair <float, Color> lastPoint = colorPoints.ElementAt(0); KeyValuePair <float, Color> nextPoint = colorPoints.ElementAt(1); while (distanceInBeats >= -0.01f) { var anyLast = colorPoints.Where(x => x.Key <= endTime - distanceInBeats).LastOrDefault(); if (anyLast.Key != lastPoint.Key) { var nextPoints = colorPoints.Where(x => x.Key > endTime - distanceInBeats); // Don't progress if this is the last gradient if (nextPoints.Any()) { lastPoint = anyLast; nextPoint = nextPoints.First(); } } float progress = (originalDistance - distanceInBeats) / originalDistance; float newTime = (progress * originalDistance) + startTime; var lerp = _easing(Mathf.InverseLerp(lastPoint.Key, nextPoint.Key, newTime)); var color = Color.Lerp(lastPoint.Value, nextPoint.Value, lerp); MapEvent data = new MapEvent(newTime, type, value, new JSONObject()); data._customData.Add("_color", color); if (propMode != EventsContainer.PropMode.Off) { if (value != MapEvent.LIGHT_VALUE_BLUE_ON && value != MapEvent.LIGHT_VALUE_RED_ON && value != MapEvent.LIGHT_VALUE_OFF) { data._value = value < 5 ? MapEvent.LIGHT_VALUE_BLUE_ON : MapEvent.LIGHT_VALUE_RED_ON; } data._customData.Add("_lightID", propID); } generatedObjects.Add(data); distanceInBeats -= 1 / precision; if (alternateColors) { value = InvertColors(value); } } return(generatedObjects); }
public void UpdateLabels(EventsContainer.PropMode propMode, int eventType, int lanes = 16) { foreach (Transform children in LayerInstantiate.transform.parent.transform) { if (children.gameObject.activeSelf) { Destroy(children.gameObject); } } laneObjs.Clear(); for (int i = 0; i < lanes; i++) { int modified = (propMode == EventsContainer.PropMode.Off ? EventTypeToModifiedType(i) : i) + NoRotationLaneOffset; if (modified < 0 && propMode == EventsContainer.PropMode.Off) { continue; } var laneInfo = new LaneInfo(i, propMode != EventsContainer.PropMode.Off ? i : modified); GameObject instantiate = Instantiate(LayerInstantiate, LayerInstantiate.transform.parent); instantiate.SetActive(true); instantiate.transform.localPosition = new Vector3(propMode != EventsContainer.PropMode.Off ? i : modified, 0, 0); laneObjs.Add(laneInfo); try { TextMeshProUGUI textMesh = instantiate.GetComponentInChildren <TextMeshProUGUI>(); if (propMode != EventsContainer.PropMode.Off) { textMesh.font = UtilityAsset; if (i == 0) { textMesh.text = "All Lights"; textMesh.font = RedAsset; } else { textMesh.text = $"{LightingManagers[eventType].name} ID {i}"; if (i % 2 == 0) { textMesh.font = UtilityAsset; } else { textMesh.font = AvailableAsset; } } } else { switch (i) { case MapEvent.EVENT_TYPE_RINGS_ROTATE: textMesh.font = UtilityAsset; textMesh.text = "Ring Rotation"; break; case MapEvent.EVENT_TYPE_RINGS_ZOOM: textMesh.font = UtilityAsset; textMesh.text = "Ring Zoom"; break; case MapEvent.EVENT_TYPE_LEFT_LASERS_SPEED: textMesh.text = "Left Laser Speed"; textMesh.font = UtilityAsset; break; case MapEvent.EVENT_TYPE_RIGHT_LASERS_SPEED: textMesh.text = "Right Laser Speed"; textMesh.font = UtilityAsset; break; case MapEvent.EVENT_TYPE_EARLY_ROTATION: textMesh.text = "Rotation (Include)"; textMesh.font = UtilityAsset; break; case MapEvent.EVENT_TYPE_LATE_ROTATION: textMesh.text = "Rotation (Exclude)"; textMesh.font = UtilityAsset; break; case MapEvent.EVENT_TYPE_BOOST_LIGHTS: textMesh.text = "Boost Lights"; textMesh.font = UtilityAsset; break; default: if (LightingManagers.Length > i) { LightsManager customLight = LightingManagers[i]; textMesh.text = customLight?.name; textMesh.font = AvailableAsset; } else { Destroy(textMesh); laneObjs.Remove(laneInfo); } break; } if (Settings.Instance.DarkTheme) { textMesh.font = darkTheme.TekoReplacement; } } laneInfo.Name = textMesh.text; } catch { } } laneObjs.Sort(); }