Esempio n. 1
0
        void GenTiming(ArcaeaFileFormatParser.EventContext context)
        {
            RejectSubevents(context, "timing");
            RejectSegment(context, "timing");
            if (!CheckValuesCount(context, "timing", 3))
            {
                return;
            }
            var timing  = CheckValueType <RawAffInt>(context.values().value()[0], "hold", "时间");
            var bpm     = CheckValueType <RawAffFloat>(context.values().value()[1], "hold", "BPM");
            var segment = CheckValueType <RawAffFloat>(context.values().value()[2], "hold", "单个小节拍数");

            if (timing == null || bpm == null || segment == null)
            {
                return;
            }
            bool valueError = false;

            if (segment.data < 0)
            {
                chart.warning.Add($"第 {context.values().value()[2].Start.Line + lineOffset} 行第 {context.values().value()[2].Start.Column + 1} 列,timing 事件的单个小节拍数小于 0,此 timing 将被忽略");
                valueError = true;
            }
            if (!valueError)
            {
                context.value = new RawAffTiming()
                {
                    Timing = timing.data, Bpm = bpm.data, BeatsPerLine = segment.data
                };
            }
        }
Esempio n. 2
0
 void RejectSegment(ArcaeaFileFormatParser.EventContext context, string type)
 {
     if (context.segment() != null)
     {
         chart.warning.Add($"第 {context.subevents().Start.Line + lineOffset} 行第 {context.subevents().Start.Column + 1} 列,{type} 事件不应包含事件块,此事件块将被忽略");
     }
 }
Esempio n. 3
0
        void GenSceneControl(ArcaeaFileFormatParser.EventContext context)
        {
            RejectSubevents(context, "scenecontrol");
            RejectSegment(context, "scenecontrol");
            if (!EnsureValuesCount(context, "scenecontrol", 2))
            {
                return;
            }
            var timing = CheckValueType <RawAffInt>(context.values().value()[0], "scenecontrol", "时间");
            var type   = CheckValueType <RawAffWord>(context.values().value()[1], "scenecontrol", "类型");

            if (timing == null || type == null)
            {
                return;
            }
            List <IRawAffValue> @params = new List <IRawAffValue>();

            foreach (var value in context.values().value().Skip(2))
            {
                if (value.value == null)
                {
                    return;
                }
                @params.Add(value.value);
            }
            context.value = new RawAffSceneControl()
            {
                Timing = timing.data,
                Type   = type.data,
                Params = @params,
            };
        }
Esempio n. 4
0
        void GenTap(ArcaeaFileFormatParser.EventContext context)
        {
            RejectSubevents(context, "tap");
            RejectSegment(context, "tap");
            if (!CheckValuesCount(context, "tap", 2))
            {
                return;
            }
            var timing = CheckValueType <RawAffInt>(context.values().value()[0], "tap", "时间");
            var track  = CheckValueType <RawAffInt>(context.values().value()[1], "tap", "轨道");

            if (timing == null || track == null)
            {
                return;
            }
            bool valueError = false;

            if (track.data > 4 || track.data <= 0)
            {
                chart.warning.Add($"第 {context.values().value()[1].Start.Line + lineOffset} 行第 {context.values().value()[1].Start.Column + 1} 列,tap 事件的轨道参数超过范围,此 tap 将被忽略");
                valueError = true;
            }
            if (!valueError)
            {
                context.value = new RawAffTap()
                {
                    Timing = timing.data, Track = track.data
                };
            }
        }
Esempio n. 5
0
 bool LimitValuesCount(ArcaeaFileFormatParser.EventContext context, string type, int count)
 {
     if (context.values().value().Length > count)
     {
         chart.warning.Add($"第 {context.values().Start.Line + lineOffset} 行第 {context.values().Start.Column + 1} 列,{type} 事件的参数个数应当为至多 {count} 个而非 {context.values().value().Length} 个,此事件将被忽略");
         return(false);
     }
     return(true);
 }
Esempio n. 6
0
        void GenCamera(ArcaeaFileFormatParser.EventContext context)
        {
            RejectSubevents(context, "camera");
            RejectSegment(context, "camera");
            if (!CheckValuesCount(context, "camera", 9))
            {
                return;
            }
            var timing        = CheckValueType <RawAffInt>(context.values().value()[0], "camera", "时间");
            var moveX         = CheckValueType <RawAffFloat>(context.values().value()[1], "camera", "平移 X 轴");
            var moveY         = CheckValueType <RawAffFloat>(context.values().value()[2], "camera", "平移 Y 轴");
            var moveZ         = CheckValueType <RawAffFloat>(context.values().value()[3], "camera", "平移 Z 轴");
            var rotateX       = CheckValueType <RawAffFloat>(context.values().value()[4], "camera", "旋转 X 轴");
            var rotateY       = CheckValueType <RawAffFloat>(context.values().value()[5], "camera", "旋转 Y 轴");
            var rotateZ       = CheckValueType <RawAffFloat>(context.values().value()[6], "camera", "旋转 Z 轴");
            var rawCameraType = CheckValueType <RawAffWord>(context.values().value()[7], "camera", "camera 类型");
            var cameraType    = ParseWord <CameraEaseType>(cameraTypes, rawCameraType.data, context.values().value()[7], "camera", "camera 类型");
            var duration      = CheckValueType <RawAffInt>(context.values().value()[8], "camera", "时长");

            if (timing == null || moveX == null || moveY == null || moveZ == null || rotateX == null || rotateY == null || rotateZ == null || cameraType == null || duration == null)
            {
                return;
            }
            bool valueError = false;

            if (duration.data < 0)
            {
                chart.warning.Add($"第 {context.values().value()[8].Start.Line + lineOffset} 行第 {context.values().value()[8].Start.Column + 1} 列,camera 事件的时长小于零,作为修复其时长见会被设为零");
                duration.data = 0;
            }
            if (!valueError)
            {
                context.value = new RawAffCamera()
                {
                    Timing     = timing.data,
                    MoveX      = moveX.data,
                    MoveY      = moveY.data,
                    MoveZ      = moveZ.data,
                    RotateX    = rotateX.data,
                    RotateY    = rotateY.data,
                    RotateZ    = rotateZ.data,
                    CameraType = cameraType.Value,
                    Duration   = duration.data,
                };
            }
        }
Esempio n. 7
0
        void GenArctap(ArcaeaFileFormatParser.EventContext context)
        {
            RejectSubevents(context, "arctap");
            RejectSegment(context, "arctap");
            if (!CheckValuesCount(context, "arctap", 1))
            {
                return;
            }
            var timing = CheckValueType <RawAffInt>(context.values().value()[0], "arctap", "时间");

            if (timing == null)
            {
                return;
            }
            context.value = new RawAffArctap()
            {
                Timing = timing.data
            };
        }
Esempio n. 8
0
 public override void ExitEvent(ArcaeaFileFormatParser.EventContext context)
 {
     if (context.Word() == null)
     {
         GenTap(context);
     }
     else
     {
         string tag = context.Word().GetText();
         if (tag == "hold")
         {
             GenHold(context);
         }
         else if (tag == "timing")
         {
             GenTiming(context);
         }
         else if (tag == "arc")
         {
             GenArc(context);
         }
         else if (tag == "arctap")
         {
             GenArctap(context);
         }
         else if (tag == "camera")
         {
             GenCamera(context);
         }
         else if (tag == "scenecontrol")
         {
             GenSceneControl(context);
         }
         else if (tag == "timinggroup")
         {
             GenTimingGroup(context);
         }
         else
         {
             chart.warning.Add($"第 {context.Start.Line + lineOffset} 行第 {context.Start.Column + 1} 列,不支持的事件类型:{context.Word().GetText()},该事件将被忽略");
         }
     }
 }
Esempio n. 9
0
        void GenTimingGroup(ArcaeaFileFormatParser.EventContext context)
        {
            RejectSubevents(context, "timinggroup");
            LimitValuesCount(context, "timinggroup", 1);
            List <IRawAffNestableItem> items           = new List <IRawAffNestableItem>();
            TimingGroupType?           timingGroupType = TimingGroupType.Normal;

            if (context.values().value().Length > 0)
            {
                var rawTimingGroupType = CheckValueType <RawAffWord>(context.values().value()[0], "arc", "arc 类型");
                timingGroupType = ParseWord(timingGroupTypes, rawTimingGroupType.data, context.values().value()[0], "arc", "arc 类型");
            }
            foreach (var item in context.segment().body().item())
            {
                IRawAffEvent @event = item.@event().value;
                if (!(@event is IRawAffItem))
                {
                    chart.warning.Add($"第 {item.@event().Start.Line + lineOffset} 行第 {item.@event().Start.Column + 1} 列,不可作为物件使用的事件:{item.@event().GetText()},此事件将被忽略");
                    continue;
                }
                IRawAffItem rawItem = @event as IRawAffItem;
                if (!(rawItem is IRawAffNestableItem))
                {
                    chart.warning.Add($"第 {item.Start.Line + lineOffset} 行第 {item.Start.Column + 1} 列,不可在 timinggroup 中嵌套使用的物件:{item.@event().GetText()},此物件将被忽略");
                    nonNestableItems.Add(rawItem);
                    continue;
                }
                items.Add(rawItem as IRawAffNestableItem);
            }
            if (timingGroupType == null)
            {
                return;
            }
            context.value = new RawAffTimingGroup()
            {
                Items = items,
                Type  = timingGroupType.Value,
            };
        }
Esempio n. 10
0
        void GenHold(ArcaeaFileFormatParser.EventContext context)
        {
            RejectSubevents(context, "hold");
            RejectSegment(context, "hold");
            if (!CheckValuesCount(context, "hold", 3))
            {
                return;
            }
            var timing    = CheckValueType <RawAffInt>(context.values().value()[0], "hold", "时间");
            var endTiming = CheckValueType <RawAffInt>(context.values().value()[1], "hold", "结束时间");
            var track     = CheckValueType <RawAffInt>(context.values().value()[2], "hold", "轨道");

            if (timing == null || endTiming == null || track == null)
            {
                return;
            }
            bool valueError = false;

            if (endTiming.data < timing.data)
            {
                chart.warning.Add($"第 {context.values().value()[1].Start.Line + lineOffset} 行第 {context.values().value()[1].Start.Column + 1} 列,hold 事件的结束时间早于开始时间,作为修复将会交换起止时间");
                var tmp = timing;
                timing    = endTiming;
                endTiming = tmp;
            }
            if (track.data > 4 || track.data <= 0)
            {
                chart.warning.Add($"第 {context.values().value()[2].Start.Line + lineOffset} 行第 {context.values().value()[2].Start.Column + 1} 列,hold 事件的轨道参数超过范围,此 hold 将被忽略");
                valueError = true;
            }
            if (!valueError)
            {
                context.value = new RawAffHold()
                {
                    Timing = timing.data, EndTiming = endTiming.data, Track = track.data
                };
            }
        }
Esempio n. 11
0
        void GenArc(ArcaeaFileFormatParser.EventContext context)
        {
            RejectSegment(context, "arc");
            if (!CheckValuesCount(context, "arc", 10))
            {
                return;
            }
            var timing      = CheckValueType <RawAffInt>(context.values().value()[0], "arc", "时间");
            var endTiming   = CheckValueType <RawAffInt>(context.values().value()[1], "arc", "结束时间");
            var xStart      = CheckValueType <RawAffFloat>(context.values().value()[2], "arc", "起点横坐标");
            var xEnd        = CheckValueType <RawAffFloat>(context.values().value()[3], "arc", "终点横坐标");
            var rawLineType = CheckValueType <RawAffWord>(context.values().value()[4], "arc", "arc 类型");
            var lineType    = ParseWord(lineTypes, rawLineType.data, context.values().value()[4], "arc", "arc 类型");
            var yStart      = CheckValueType <RawAffFloat>(context.values().value()[5], "arc", "起点纵坐标");
            var yEnd        = CheckValueType <RawAffFloat>(context.values().value()[6], "arc", "终点纵坐标");
            var color       = CheckValueType <RawAffInt>(context.values().value()[7], "arc", "颜色");
            var effect      = CheckValueType <RawAffWord>(context.values().value()[8], "arc", "效果类型");
            var rawIsVoid   = CheckValueType <RawAffWord>(context.values().value()[9], "arc", "是否黑线");
            var isVoid      = ParseWord(bools, rawIsVoid.data, context.values().value()[9], "arc", "是否黑线");

            if (timing == null || endTiming == null || xStart == null || xEnd == null || lineType == null || yStart == null || yEnd == null || color == null || effect == null || isVoid == null)
            {
                return;
            }
            bool valueError = false;

            if (endTiming.data < timing.data)
            {
                chart.warning.Add($"第 {context.values().value()[1].Start.Line + lineOffset} 行第 {context.values().value()[1].Start.Column + 1} 列,arc 事件的结束时间早于开始时间,作为修复将会交换起止时间");
                var tmp = timing;
                timing    = endTiming;
                endTiming = tmp;
            }
            if (color.data < 0 || color.data >= 3)
            {
                chart.warning.Add($"第 {context.values().value()[7].Start.Line + lineOffset} 行第 {context.values().value()[7].Start.Column + 1} 列,arc 事件的颜色超出范围,作为修复其颜色见会被设为红色");
                color.data = 0;
            }
            List <RawAffArctap> arctaps = new List <RawAffArctap>();
            var subevents = context.subevents();

            if (subevents != null)
            {
                foreach (var @event in context.subevents().@event())
                {
                    if (@event.value != null)
                    {
                        if (@event.value is RawAffArctap)
                        {
                            var arctap = @event.value as RawAffArctap;
                            if (arctap.Timing < timing.data || arctap.Timing > endTiming.data)
                            {
                                chart.warning.Add($"第 {@event.values().value()[0].Start.Line + lineOffset} 行第 {@event.values().value()[0].Start.Column + 1} 列,arctap 事件的时间超出所属 arc 的时间范围,此 arctap 事件将被忽略");
                            }
                            else
                            {
                                arctaps.Add(arctap);
                            }
                        }
                        else
                        {
                            chart.warning.Add($"第 {@event.Start.Line + lineOffset} 行第 {@event.Start.Column + 1} 列,arc 事件的子事件必须为 arctap 事件,此事件将被忽略");
                        }
                    }
                }
            }
            if (!valueError)
            {
                context.value = new RawAffArc()
                {
                    Timing    = timing.data,
                    EndTiming = endTiming.data,
                    XStart    = xStart.data,
                    XEnd      = xEnd.data,
                    LineType  = lineType.Value,
                    YStart    = yStart.data,
                    YEnd      = yEnd.data,
                    Color     = color.data,
                    IsVoid    = isVoid.Value,
                    ArcTaps   = arctaps,
                };
            }
        }
 /// <summary>
 /// Exit a parse tree produced by <see cref="ArcaeaFileFormatParser.event"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitEvent([NotNull] ArcaeaFileFormatParser.EventContext context)
 {
 }