/// <summary>
        /// イベントコマンドの動作指定コマンド
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <param name="actionEntry">データ格納先</param>
        /// <exception cref="InvalidOperationException">ファイル仕様が異なる場合</exception>
        private void ReadEventActionEntry(FileReadStatus status, ActionEntry actionEntry)
        {
            Logger.Debug(FileIOMessage.StartCommonRead(typeof(EventCommandListReader),
                                                       "動作指定コマンド"));

            // ヘッダチェック
            foreach (var b in ActionEntry.HeaderBytes)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"イベントコマンド中のイベントコマンドヘッダの値が異なります。(offset: {status.Offset})");
                }

                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(EventCommandListReader),
                                               "動作指定コマンドヘッダ"));

            // 動作フラグ
            var optionFlag = status.ReadByte();

            actionEntry.SetOptionFlag(optionFlag);
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(EventCommandListReader),
                                                   "数値変数の数", optionFlag));

            // 動作コマンドリスト
            actionEntry.CommandList = ReadCharaMoveCommand(status);

            Logger.Debug(FileIOMessage.EndCommonRead(typeof(EventCommandListReader),
                                                     "動作指定コマンド"));
        }
        /// <summary>
        /// コモンイベント末尾A
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <returns>あとに返戻値が続く場合true</returns>
        /// <exception cref="InvalidOperationException">データが仕様と異なる場合</exception>
        private HasNext ReadFooterA(FileReadStatus status)
        {
            var b1 = status.ReadByte();

            if (b1 == CommonEvent.BeforeReturnValueSummaryBytesBefore[0])
            {
                foreach (var b in CommonEvent.BeforeReturnValueSummaryBytesBefore)
                {
                    if (status.ReadByte() != b)
                    {
                        throw new InvalidOperationException(
                                  $"ファイルデータが仕様と異なります。(offset:{status.Offset})");
                    }
                    status.IncreaseByteOffset();
                }


                Logger.Debug(FileIOMessage.CheckOk(typeof(CommonEventReader),
                                                   "コモンイベント末尾", "(返戻値あり)"));

                return(HasNext.Yes);
            }

            if (b1 == CommonEvent.FooterBytesBeforeVer2_00[0])
            {
                status.IncreaseByteOffset();
                return(HasNext.No);
            }

            throw new InvalidOperationException(
                      $"ファイルデータが仕様と異なります。(offset:{status.Offset})");
        }
        /// <summary>
        /// 特殊引数リストを読み込み、返す。
        /// </summary>
        /// <returns>特殊引数リスト</returns>
        /// <exception cref="InvalidOperationException">ファイル仕様が異なる場合</exception>
        public void Read()
        {
            try
            {
                Logger.Debug(FileIOMessage.StartCommonRead(typeof(SpecialArgDescReader),
                                                           "特殊引数リスト"));

                // ヘッダ
                foreach (var b in CommonEventSpecialArgDescList.Header)
                {
                    if (Status.ReadByte() != b)
                    {
                        throw new InvalidOperationException(
                                  $"ファイルデータが仕様と異なります。(offset:{Status.Offset})");
                    }
                    Status.IncreaseByteOffset();
                }

                Logger.Debug(FileIOMessage.CheckOk(typeof(SpecialArgDescReader),
                                                   "ヘッダ"));

                // 引数名
                var argNameList      = ReadArgNames(Status);
                var argNameListCount = argNameList.Count;
                NumberArgNameList = argNameList.Take(argNameListCount / 2).ToList();
                StringArgNameList = argNameList.Skip(argNameListCount / 2).ToList();
                // 引数特殊指定
                var argTypeList      = ReadSpecialArgType(Status);
                var argTypeListCount = argTypeList.Count;
                NumberArgTypeList = argTypeList.Take(argTypeListCount / 2).ToList();
                StringArgTypeList = argTypeList.Skip(argTypeListCount / 2).ToList();
                // 数値特殊指定文字列パラメータ
                var stringArgLists      = ReadSpecialStringArgList(Status);
                var stringArgListsCount = stringArgLists.Count;
                NumberArgStringParamsList = stringArgLists.Take(stringArgListsCount / 2).ToList();
                StringArgStringParamsList = stringArgLists.Skip(stringArgListsCount / 2).ToList();
                // 数値特殊指定数値パラメータ
                var numberArgLists      = ReadSpecialNumberArgList(Status);
                var numberArgListsCount = numberArgLists.Count;
                NumberArgNumberParamsList = numberArgLists.Take(numberArgListsCount / 2).ToList();
                StringArgNumberParamsList = numberArgLists.Skip(numberArgListsCount / 2).ToList();
                // 数値特殊指定数値初期値
                NumberArgInitValueList = ReadInitValue(Status);

                Logger.Debug(FileIOMessage.EndCommonRead(typeof(SpecialArgDescReader),
                                                         "特殊引数リスト"));
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(
                          $"引数特殊指定データが仕様と異なります。(offset:{Status.Offset})", ex);
            }
        }
        /// <summary>
        /// コモンイベントヘッダ
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <exception cref="InvalidOperationException">ヘッダが仕様と異なる場合</exception>
        private void ReadHeader(FileReadStatus status)
        {
            foreach (var b in CommonEvent.HeaderBytes)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"ファイルヘッダが仕様と異なります。(offset:{status.Offset})");
                }
                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(CommonEventReader), "コモンイベントヘッダ"));
        }
        /// <summary>
        /// セルフ変数名の後のチェックディジット
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <exception cref="InvalidOperationException">データが仕様と異なる場合</exception>
        private void ReadAfterMemoBytesSelfVariableNamesBytes(FileReadStatus status)
        {
            foreach (var b in CommonEvent.AfterMemoBytesSelfVariableNamesBytes)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"ファイルデータが仕様と異なります。(offset:{status.Offset})");
                }
                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(CommonEventReader),
                                               "セルフ変数後のチェックディジット", "(返戻値あり)"));
        }
        /// <summary>
        /// 引数初期値後のチェックディジット
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <exception cref="InvalidOperationException">データが仕様と異なる場合</exception>
        private void ReadAfterInitValueBytes(FileReadStatus status)
        {
            foreach (var b in CommonEvent.AfterInitValueBytes)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"ファイルデータが仕様と異なります。(offset:{status.Offset})");
                }
                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(CommonEventReader),
                                               "引数初期値後のチェックディジット"));
        }
Example #7
0
        /// <summary>
        /// セパレータ
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        private void ReadSeparator(FileReadStatus status)
        {
            var read = status.ReadByte();

            if (read != TileSetSetting.DataSeparator)
            {
                throw new InvalidOperationException(
                          $"データセパレータが正しく読み込めませんでした。(offset:{status.Offset})");
            }

            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.CheckOk(typeof(TileSetFileReader),
                                               "データセパレータ"));
        }
        /// <summary>
        /// ヘッダ
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <exception cref="InvalidOperationException">ファイルヘッダが仕様と異なる場合</exception>
        private void ReadHeader(FileReadStatus status)
        {
            foreach (var b in MapTreeData.Header)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"ファイルヘッダがファイル仕様と異なります(offset:{status.Offset})");
                }

                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(MapTreeDataFileReader),
                                               "ヘッダ"));
        }
Example #9
0
        /// <summary>
        /// フッタ
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <exception cref="InvalidOperationException">ファイルフッタが仕様と異なる場合</exception>
        private void ReadFooter(FileReadStatus status)
        {
            foreach (var b in TileSetFileData.Footer)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"ファイルフッタがファイル仕様と異なります(offset:{status.Offset})");
                }

                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(TileSetFileReader),
                                               "フッタ"));
        }
Example #10
0
        /// <summary>
        /// フッタ
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <exception cref="InvalidOperationException">ファイル仕様が異なる場合</exception>
        private void ReadFooter(FileReadStatus status)
        {
            foreach (var b in MapData.Footer)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"フッタが正常に取得できませんでした。(offset:{status.Offset})");
                }

                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(EventCommandListReader),
                                               "フッタ"));
        }
        /// <summary>
        /// 動作指定コマンド
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <param name="commandList">データ格納先</param>
        /// <exception cref="InvalidOperationException">ファイル仕様が異なる場合</exception>
        private void ReadCharaMoveCommand(FileReadStatus status, ICollection <ICharaMoveCommand> commandList)
        {
            // 動作指定コード
            var charaMoveCode = status.ReadByte();
            CharaMoveCommandCode commandCode;

            try
            {
                commandCode = CharaMoveCommandCode.FromByte(charaMoveCode);
            }
            catch
            {
                throw new InvalidOperationException(
                          $"存在しない動作指定コマンドコードが読み込まれました。" +
                          $"(コマンドコード値:{charaMoveCode}, offset:{status.Offset}");
            }

            var charaMoveCommand = CharaMoveCommandFactory.CreateRaw(commandCode);

            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(EventCommandListReader),
                                                   "動作指定コード", charaMoveCode));

            // 変数の数
            var varLength = status.ReadByte();

            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(EventCommandListReader),
                                                   "変数の数", charaMoveCode));

            // 変数
            for (var i = 0; i < varLength; i++)
            {
                var value = status.ReadInt();
                charaMoveCommand.SetNumberValue(i, value);
                status.IncreaseIntOffset();

                Logger.Debug(FileIOMessage.SuccessRead(typeof(EventCommandListReader),
                                                       $"変数{i}", value));
            }

            // 終端コードチェック
            foreach (var b in CharaMoveCommandBase.EndBlockCode)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"動作指定コマンド末尾の値が異なります。(offset: {status.Offset})");
                }

                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(EventCommandListReader),
                                               $"終端コード"));

            // 結果
            commandList.Add(charaMoveCommand);
        }
Example #12
0
        /// <summary>
        /// マップイベントページ
        /// </summary>
        /// <param name="status">読み込み経過状態</param>
        /// <param name="mapEventPages">格納先リスト</param>
        /// <exception cref="InvalidOperationException">ファイル仕様が異なる場合</exception>
        private void ReadMapEventOnePage(FileReadStatus status, ICollection <MapEventPage> mapEventPages)
        {
            var result = new MapEventPage();

            // ヘッダチェック
            foreach (var b in MapEventPage.Header)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"マップイベントページのヘッダが異なります。(offset: {status.Offset})");
                }

                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(MpsFileReader),
                                               "マップイベントページヘッダ"));

            var graphicInfo = new MapEventPageGraphicInfo();

            // タイル画像ID
            var graphicTileId = (MapEventTileId)status.ReadInt();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページタイル画像ID", graphicTileId));

            if (graphicTileId != MapEventTileId.NotUse)
            {
                graphicInfo.IsGraphicTileChip = true;
                graphicInfo.GraphicTileId     = graphicTileId;
            }

            status.IncreaseIntOffset();

            // キャラチップ名
            var charaChipString = status.ReadString();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページキャラチップ名", charaChipString.String));

            if (!graphicInfo.IsGraphicTileChip)
            {
                graphicInfo.CharaChipFilePath = charaChipString.String;
            }

            status.AddOffset(charaChipString.ByteLength);

            // 初期キャラ向き
            var initDirection = status.ReadByte();

            graphicInfo.InitDirection = CharaChipDirection.FromByte(initDirection);
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページ初期キャラ向き", graphicInfo.InitDirection));

            // 初期アニメーション番号
            graphicInfo.InitAnimationId = status.ReadByte();
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページ初期アニメーション番号", graphicInfo.InitAnimationId));

            // キャラチップ透過度
            graphicInfo.CharaChipOpacity = status.ReadByte();
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページキャラチップ透過度", graphicInfo.CharaChipOpacity));

            // キャラチップ表示形式
            graphicInfo.CharaChipDrawType = PictureDrawType.FromByte(status.ReadByte());
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページキャラチップ表示形式", graphicInfo.CharaChipDrawType));

            result.GraphicInfo = graphicInfo;

            var bootInfo = new MapEventPageBootInfo();

            // 起動条件
            bootInfo.MapEventBootType = MapEventBootType.FromByte(status.ReadByte());
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページ起動条件", bootInfo.MapEventBootType));

            // 条件1~4演算子 & 使用フラグ
            var conditions = new List <MapEventBootCondition>
            {
                new MapEventBootCondition(),
                new MapEventBootCondition(),
                new MapEventBootCondition(),
                new MapEventBootCondition(),
            };

            for (var i = 0; i < 4; i++)
            {
                conditions[i].Operation    = CriteriaOperator.FromByte((byte)(status.ReadByte() & 0xF0));
                conditions[i].UseCondition = (byte)(status.ReadByte() & 0x0F) != 0;
                status.IncreaseByteOffset();

                Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                       $"マップイベントページ起動条件{i}演算子", conditions[i].Operation));
                Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                       $"マップイベントページ起動条件{i}使用フラグ", conditions[i].UseCondition));
            }

            // 条件1~4左辺
            for (var i = 0; i < 4; i++)
            {
                conditions[i].LeftSide = status.ReadInt();
                status.IncreaseIntOffset();

                Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                       $"マップイベントページ起動条件{i}左辺", conditions[i].LeftSide));
            }

            // 条件1~4右辺
            for (var i = 0; i < 4; i++)
            {
                conditions[i].RightSide = status.ReadInt();
                status.IncreaseIntOffset();
                bootInfo.SetEventBootCondition(i, conditions[i]);

                Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                       $"マップイベントページ起動条件{i}右辺", conditions[i].RightSide));
            }

            result.BootInfo = bootInfo;

            var moveRouteInfo = new MapEventPageMoveRouteInfo();

            // アニメ速度
            moveRouteInfo.AnimateSpeed = AnimateSpeed.FromByte(status.ReadByte());
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページアニメ速度", moveRouteInfo.AnimateSpeed));

            // 移動速度
            moveRouteInfo.MoveSpeed = MoveSpeed.FromByte(status.ReadByte());
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページ移動速度", moveRouteInfo.MoveSpeed));

            // 移動頻度
            moveRouteInfo.MoveFrequency = MoveFrequency.FromByte(status.ReadByte());
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページ移動頻度", moveRouteInfo.MoveFrequency));

            // 移動ルート
            moveRouteInfo.MoveType = MoveType.FromByte(status.ReadByte());
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページ移動ルート種別", moveRouteInfo.MoveType));

            var option = new MapEventPageOption();

            // オプション
            var optionByte = status.ReadByte();

            option.SetOptionFlag(optionByte);
            status.IncreaseByteOffset();

            result.Option = option;

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページオプション", optionByte));

            // カスタム移動ルートフラグ
            var actionEntry         = new ActionEntry();
            var customMoveRouteFlag = status.ReadByte();

            actionEntry.SetOptionFlag(customMoveRouteFlag);
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページカスタム移動ルートフラグ", customMoveRouteFlag));

            // 動作指定コマンド数
            actionEntry.CommandList = ReadCharaMoveCommand(status);

            moveRouteInfo.CustomMoveRoute = actionEntry;
            result.MoveRouteInfo          = moveRouteInfo;

            // イベント行数
            var eventLength = status.ReadInt();

            status.IncreaseIntOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページイベント行数", eventLength));

            // イベントコマンド
            var eventCommandListReader = new EventCommandListReader(status, eventLength);

            result.EventCommands = eventCommandListReader.Read();

            // イベントコマンド終端チェック
            foreach (var b in EventCommandList.EndEventCommand)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"イベントコマンド後の値が異なります。(offset: {status.Offset})");
                }

                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(MpsFileReader),
                                               "マップイベントページイベントコマンド終端"));

            // 影グラフィック番号
            result.ShadowGraphicId = status.ReadByte();
            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページ影グラフィック番号", result.ShadowGraphicId));

            // 接触範囲拡張X
            var rangeWidth = status.ReadByte();

            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページ接触範囲拡張X", rangeWidth));

            // 接触範囲拡張Y
            var rangeHeight = status.ReadByte();

            status.IncreaseByteOffset();

            Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                   "マップイベントページ接触範囲拡張Y", rangeHeight));

            result.HitExtendRange = (rangeWidth, rangeHeight);

            // イベントページ末尾チェック
            foreach (var b in MapEventPage.Footer)
            {
                if (status.ReadByte() != b)
                {
                    throw new InvalidOperationException(
                              $"イベントページ末尾の値が異なります。(offset: {status.Offset})");
                }

                status.IncreaseByteOffset();
            }

            Logger.Debug(FileIOMessage.CheckOk(typeof(MpsFileReader),
                                               "マップイベントページ末尾チェック"));

            // 完了
            mapEventPages.Add(result);
        }
Example #13
0
        /// <summary>
        /// マップイベント
        /// </summary>
        /// <param name="size">マップイベント数</param>
        /// <param name="status">読み込み経過状態</param>
        /// <param name="mapData">読み込み経過状態</param>
        /// <exception cref="InvalidOperationException">ファイル仕様が異なる場合</exception>
        private void ReadMapEvent(int size, FileReadStatus status, MapData mapData)
        {
            Logger.Debug(FileIOMessage.StartCommonRead(typeof(MpsFileReader),
                                                       "マップイベント"));

            var mapEvents = new List <MapEvent>();
            var count     = 0;

            while (true)
            {
                Logger.Debug(FileIOMessage.StartCommonRead(typeof(MpsFileReader),
                                                           $"マップイベント{count}"));

                // ヘッダチェック
                var validatedHeader = status.ReadByte() == MapEvent.Header[0];
                if (!validatedHeader)
                {
                    break;
                }


                Logger.Debug(FileIOMessage.CheckOk(typeof(MpsFileReader),
                                                   "ヘッダ"));

                // ヘッダ分オフセット加算
                status.AddOffset(MapEvent.Header.Length);

                var mapEvent = new MapEvent();

                // マップイベントID
                mapEvent.MapEventId = status.ReadInt();
                status.IncreaseIntOffset();

                Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                       "マップイベントID", mapEvent.MapEventId));

                // イベント名
                var woditorString = status.ReadString();
                mapEvent.EventName = woditorString.String;
                status.AddOffset(woditorString.ByteLength);

                Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                       "イベント名", mapEvent.EventName));

                // X座標
                var posX = status.ReadInt();
                status.IncreaseIntOffset();

                Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                       "X座標", posX));

                // Y座標
                var posY = status.ReadInt();
                status.IncreaseIntOffset();

                Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                       "Y座標", posY));

                mapEvent.Position = (posX, posY);

                // イベントページ数
                var pageLength = status.ReadInt();
                status.IncreaseIntOffset();

                Logger.Debug(FileIOMessage.SuccessRead(typeof(MpsFileReader),
                                                       "イベントページ数", pageLength));

                // 0パディングチェック
                var padding = status.ReadInt();
                status.IncreaseIntOffset();
                var isCorrectPadding = padding == 0;
                if (!isCorrectPadding)
                {
                    throw new InvalidOperationException(
                              $"マップイベントのパディングが異なります。(offset:{status.Offset})");
                }

                Logger.Debug(FileIOMessage.CheckOk(typeof(MpsFileReader),
                                                   "0パディング"));

                // マップイベントページ
                var mapEventPageList = new List <MapEventPage>();
                for (var i = 0; i < pageLength; i++)
                {
                    Logger.Debug(FileIOMessage.StartCommonRead(typeof(MpsFileReader),
                                                               $"マップイベントページ{i}"));

                    ReadMapEventOnePage(status, mapEventPageList);

                    Logger.Debug(FileIOMessage.EndCommonRead(typeof(MpsFileReader),
                                                             $"マップイベントページ{i}"));
                }

                mapEvent.MapEventPageList = new MapEventPageList(mapEventPageList);

                // イベントページ末尾チェック
                foreach (var b in MapEvent.Footer)
                {
                    if (status.ReadByte() != b)
                    {
                        throw new InvalidOperationException(
                                  $"マップイベント末尾の値が異なります。(offset: {status.Offset})");
                    }

                    status.IncreaseByteOffset();
                }

                Logger.Debug(FileIOMessage.CheckOk(typeof(MpsFileReader),
                                                   "イベントページ末尾"));

                mapEvents.Add(mapEvent);

                Logger.Debug(FileIOMessage.EndCommonRead(typeof(MpsFileReader),
                                                         $"マップイベント{count}"));

                count++;
            }

            if (count != size)
            {
                throw new InvalidOperationException(
                          $"マップイベントデータの数が期待する数と異なります。(期待する数:{size}, 実際のイベント数:{count})");
            }

            Logger.Debug(FileIOMessage.EndCommonRead(typeof(MpsFileReader),
                                                     "マップイベント"));

            mapData.MapEvents = new MapEventList(mapEvents);
        }