/// <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), "引数初期値後のチェックディジット")); }
/// <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), "ヘッダ")); }
/// <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), "フッタ")); }
/// <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); }
/// <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); }
/// <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); }