private void ProcessTickOptions(BeatmapKsh.Tick tick) { TimingPoint newTimingPoint = null; // Process tick options foreach (var option in tick.Options) { var key = option.Key; if (key == "beat") { if (tickIndex == 0) { // Special case where the first tick has a beat option if (measureIndex == 0) { ParseBeatOption(option.Value, currentTimingPoint); } else { if (newTimingPoint == null) { newTimingPoint = new TimingPoint(); newTimingPoint.BPM = currentTimingPoint.BPM; } ParseBeatOption(option.Value, newTimingPoint); } } else { if (pendingTimingPoint == null) { pendingTimingPoint = new TimingPoint(); } pendingTimingPoint.BPM = currentTimingPoint.BPM; ParseBeatOption(option.Value, pendingTimingPoint); } } else if (key == "t") { if (tickIndex == 0) { // Special case where the first tick has a timing option if (measureIndex == 0) { currentTimingPoint.BPM = double.Parse(option.Value); continue; } } if (newTimingPoint == null) { newTimingPoint = new TimingPoint(); newTimingPoint.Numerator = currentTimingPoint.Numerator; newTimingPoint.Denominator = currentTimingPoint.Denominator; } newTimingPoint.BPM = double.Parse(option.Value); } else if (key == "laserrange_l") { laserExtended[0] = true; } else if (key == "laserrange_r") { laserExtended[1] = true; } else if (key == "fx-l") { SetEffectTypeAndParameters(ObjectFilter.Fx0, option.Value); } else if (key == "fx-r") { SetEffectTypeAndParameters(ObjectFilter.Fx1, option.Value); } else if (key == "fx-l_param1") { currentButtonEffectParameters[0][0] = short.Parse(option.Value); } else if (key == "fx-r_param1") { currentButtonEffectParameters[1][0] = short.Parse(option.Value); } else if (key == "filtertype") { SetEffectType(ObjectFilter.Laser0 | ObjectFilter.Laser1, option.Value); } else if (key == "pfiltergain") { AddControlPoint(float.Parse(option.Value) / 100.0f, ControlPointType.FilterMix, false); } else if (key == "chokkakuvol") { AddControlPoint(float.Parse(option.Value) / 100.0f, ControlPointType.SampleMix, false); } else if (key == "zoom_bottom") { AddControlPoint(float.Parse(option.Value) / 100.0f, ControlPointType.ZoomBottom, true); } else if (key == "zoom_top") { AddControlPoint(float.Parse(option.Value) / 100.0f, ControlPointType.ZoomTop, true); } else if (key == "tilt") { bool lockRoll = false; string value = option.Value; if (value.StartsWith("keep_")) { lockRoll = true; value = value.Substring(5); } if (rollLocked != lockRoll) { RollModifier mod = new RollModifier { Position = currentPosition, Lock = lockRoll }; currentMeasure.Objects.Add(mod); rollLocked = lockRoll; } float intensity = 1.0f; if (value == "zero") { intensity = 0.0f; } else if (value == "normal") { intensity = 1.0f; } else if (value == "bigger") { intensity = 2.0f; } else if (value == "biggest") { intensity = 3.0f; } else { throw new BeatmapParserException($"Unkown roll type {value}"); } if (intensity != rollIntensity) { AddControlPoint(intensity, ControlPointType.RollIntensity, false); rollIntensity = intensity; } } else { throw new BeatmapParserException($"Unknown option: {key}={option.Value} at {GetPositionString()}"); } } if (newTimingPoint != null) { AddNewTimingPoint(newTimingPoint); } }
private void UpdateLaserState(int index, BeatmapKsh.Tick tick) { Laser laser; TempLaserState state; if (laserStates[index] == null) { state = laserStates[index] = new TempLaserState(); // Create laser root var root = new LaserRoot(); root.IsExtended = laserExtended[index]; root.Index = index; laser = root; state.Root = root.Root = new ObjectReference(root, currentMeasure); state.LastObject = state.Root; } else { state = laserStates[index]; // Create laser point laser = new Laser(); laser.Previous = state.LastObject; laser.Root = state.Root; var myRef = new ObjectReference(laser, currentMeasure); // Calculate distance to last var lastObject = (state.LastObject.Object as Laser); lastObject.Next = myRef; state.LastObject = myRef; } laser.Position = currentPosition; laser.HorizontalPosition = tick.LaserAsFloat(index); if (laser.IsExtended) { laser.HorizontalPosition *= 2.0f; laser.HorizontalPosition -= 0.5f; } // Decide to create slam instead? var previousLaser = laser.Previous?.Object as Laser; bool createInstantSegment = false; if (previousLaser != null) { double laserSlamThreshold = currentTimingPoint.BeatDuration / 7.0; double duration = previousLaser.Next.AbsolutePosition - laser.Previous.AbsolutePosition; createInstantSegment = duration <= laserSlamThreshold && previousLaser.HorizontalPosition != laser.HorizontalPosition; } if (createInstantSegment) { laser.Previous.Measure.Objects.Add(laser); laser.Position = laser.Previous.Object.Position; } else { // Create normal control point currentMeasure.Objects.Add(laser); } // Reset tick and last measure on laser state state.NumTicks = 0; state.LastSourceMeasure = sourceMeasure; }