using System; using System.Collections.Generic; using System.Media; using NTERA.Core.Interop; using NTERA.EmuEra.Game.EraEmu.Config; using NTERA.EmuEra.Game.EraEmu.GameData.Variable; using NTERA.EmuEra.Game.EraEmu.Sub; namespace NTERA.EmuEra.Game.EraEmu.GameProc { internal sealed partial class Process { private string[] _trainName; delegate void SystemProcess(); readonly Dictionary _systemProcessDictionary = new Dictionary(); private void InitSystemProcess() { _comAble = new int[_trainName.Length]; _systemProcessDictionary.Add(SystemStateCode.Title_Begin, beginTitle); _systemProcessDictionary.Add(SystemStateCode.Openning, endOpenning); _systemProcessDictionary.Add(SystemStateCode.Train_Begin, beginTrain); _systemProcessDictionary.Add(SystemStateCode.Train_CallEventTrain, endCallEventTrain); _systemProcessDictionary.Add(SystemStateCode.Train_CallShowStatus, endCallShowStatus); _systemProcessDictionary.Add(SystemStateCode.Train_CallComAbleXX, endCallComAbleXX); _systemProcessDictionary.Add(SystemStateCode.Train_CallShowUserCom, endCallShowUserCom); _systemProcessDictionary.Add(SystemStateCode.Train_WaitInput, trainWaitInput); _systemProcessDictionary.Add(SystemStateCode.Train_CallEventCom, endEventCom); _systemProcessDictionary.Add(SystemStateCode.Train_CallComXX, endCallComXX); _systemProcessDictionary.Add(SystemStateCode.Train_CallSourceCheck, endCallSourceCheck); _systemProcessDictionary.Add(SystemStateCode.Train_CallEventComEnd, endCallEventComEnd); ; _systemProcessDictionary.Add(SystemStateCode.Train_DoTrain, doTrain); _systemProcessDictionary.Add(SystemStateCode.AfterTrain_Begin, beginAfterTrain); _systemProcessDictionary.Add(SystemStateCode.Ablup_Begin, beginAblup); _systemProcessDictionary.Add(SystemStateCode.Ablup_CallShowJuel, endCallShowJuel); _systemProcessDictionary.Add(SystemStateCode.Ablup_CallShowAblupSelect, endCallShowAblupSelect); _systemProcessDictionary.Add(SystemStateCode.Ablup_WaitInput, ablupWaitInput); _systemProcessDictionary.Add(SystemStateCode.Ablup_CallAblupXX, endCallAblupXX); _systemProcessDictionary.Add(SystemStateCode.Turnend_Begin, beginTurnend); _systemProcessDictionary.Add(SystemStateCode.Shop_Begin, beginShop); _systemProcessDictionary.Add(SystemStateCode.Shop_CallEventShop, endCallEventShop); _systemProcessDictionary.Add(SystemStateCode.Shop_CallShowShop, endCallShowShop); _systemProcessDictionary.Add(SystemStateCode.Shop_WaitInput, shopWaitInput); _systemProcessDictionary.Add(SystemStateCode.Shop_CallEventBuy, endCallEventBuy); _systemProcessDictionary.Add(SystemStateCode.SaveGame_Begin, beginSaveGame); _systemProcessDictionary.Add(SystemStateCode.SaveGame_WaitInput, saveGameWaitInput); _systemProcessDictionary.Add(SystemStateCode.SaveGame_WaitInputOverwrite, saveGameWaitInputOverwrite); _systemProcessDictionary.Add(SystemStateCode.SaveGame_CallSaveInfo, endCallSaveInfo); _systemProcessDictionary.Add(SystemStateCode.LoadGame_Begin, beginLoadGame); _systemProcessDictionary.Add(SystemStateCode.LoadGame_WaitInput, loadGameWaitInput); _systemProcessDictionary.Add(SystemStateCode.LoadGameOpenning_Begin, beginLoadGameOpening); _systemProcessDictionary.Add(SystemStateCode.LoadGameOpenning_WaitInput, loadGameWaitInput); //stateEndProcessDictionary.Add(ProgramState.AutoSave_Begin, new stateEndProcess(this.beginAutoSave)); _systemProcessDictionary.Add(SystemStateCode.AutoSave_CallSaveInfo, endAutoSaveCallSaveInfo); _systemProcessDictionary.Add(SystemStateCode.AutoSave_CallUniqueAutosave, endAutoSave); _systemProcessDictionary.Add(SystemStateCode.LoadData_DataLoaded, beginDataLoaded); _systemProcessDictionary.Add(SystemStateCode.LoadData_CallSystemLoad, endSystemLoad); _systemProcessDictionary.Add(SystemStateCode.LoadData_CallEventLoad, endEventLoad); _systemProcessDictionary.Add(SystemStateCode.Openning_TitleLoadgame, endTitleLoadgame); _systemProcessDictionary.Add(SystemStateCode.System_Reloaderb, endReloaderb); _systemProcessDictionary.Add(SystemStateCode.First_Begin, beginFirst); _systemProcessDictionary.Add(SystemStateCode.Normal, endNormal); } Int64 _systemResult; int _lastCalledComable = -1; int _lastAddCom = -1; //(Train.csv中の値・定義されていなければ-1) == comAble[(表示されている値)]; int[] _comAble;// private void RunSystemProc() { //スクリプト実行中にここには来ないはず //if (!state.ScriptEnd) // throw new ExeEE("不正な呼び出し"); //ない物を渡す処理は現状ない //if (systemProcessDictionary.ContainsKey(state.SystemState)) _systemProcessDictionary[state.SystemState](); //else // throw new ExeEE("未定義の状態"); } void SetWait() { console.ReadAnyKey(); } void SetWaitInput() { InputRequest req = new InputRequest(); req.InputType = InputType.IntValue; req.IsSystemInput = true; console.WaitInput(req); } private bool CallFunction(string functionName, bool force, bool isEvent) { CalledFunction call = null; if (isEvent) call = CalledFunction.CallEventFunction(this, functionName, null); else call = CalledFunction.CallFunction(this, functionName, null); if (call == null) if (!force) return false; else throw new CodeEE("関数\"@" + functionName + "\"が見つかりません"); //そもそも非イベント関数では関数1個分しか与えないので条件を満たすわけがない //if ((!isEvent) && (call.Count > 1)) // throw new ExeEE("イベント関数でない関数\"@" + functionName + "\"の候補が複数ある"); state.IntoFunction(call, null, null); return true; } //CheckState()から呼ばれる関数群。ScriptEndに達したときの処理。 void beginTitle() { //連続調教コマンド処理中の状態が持ち越されていたらここで消しておく if (isCTrain) if (ClearCommands()) return; skipPrint = false; console.ResetStyle(); deleteAllPrevState(); if (Program.AnalysisMode) { console.PrintSystemLine("ファイル解析終了:Analysis.logに出力します"); console.OutputLog(Program.ExeDir + "Analysis.log"); console.noOutputLog = true; console.PrintSystemLine("エンターキーもしくはクリックで終了します"); SystemSounds.Asterisk.Play(); console.ThrowTitleError(false); return; } if ((!noError) && (!Config.Config.CompatiErrorLine)) { console.PrintSystemLine("ERBコードに解釈不可能な行があるためEmueraを終了します"); console.PrintSystemLine("※互換性オプション「" + Config.Config.GetConfigName(ConfigCode.CompatiErrorLine) + "」により強制的に動作させることができます"); console.PrintSystemLine("emuera.logにログを出力します"); console.OutputLog(Program.ExeDir + "emuera.log"); console.noOutputLog = true; console.PrintSystemLine("エンターキーもしくはクリックで終了します"); //System.Media.SystemSounds.Asterisk.Play(); console.ThrowTitleError(true); return; } if (CallFunction("SYSTEM_TITLE", false, false)) {//独自定義 state.SystemState = SystemStateCode.Normal; return; } //標準のタイトル画面 console.PrintBar(); console.NewLine(); console.Alignment = DisplayLineAlignment.CENTER; console.PrintSingleLine(gamebase.ScriptTitle); if (gamebase.ScriptVersion != 0) console.PrintSingleLine(gamebase.ScriptVersionText); console.PrintSingleLine(gamebase.ScriptAutherName); console.PrintSingleLine("(" + gamebase.ScriptYear + ")"); console.NewLine(); console.PrintSingleLine(gamebase.ScriptDetail); console.Alignment = DisplayLineAlignment.LEFT; console.PrintBar(); console.NewLine(); console.PrintSingleLine("[0] " + Config.Config.TitleMenuString0); console.PrintSingleLine("[1] " + Config.Config.TitleMenuString1); openingInput(); } void openingInput() { SetWaitInput(); state.SystemState = SystemStateCode.Openning; } void endOpenning() { if (_systemResult == 0) {//[0] 最初からはじめる vEvaluator.ResetData(); //vEvaluator.AddCharacter(0, false); vEvaluator.AddCharacterFromCsvNo(0); if (gamebase.DefaultCharacter > 0) //vEvaluator.AddCharacter(gamebase.DefaultCharacter, false); vEvaluator.AddCharacterFromCsvNo(gamebase.DefaultCharacter); console.PrintBar(); console.NewLine(); beginFirst(); } else if (_systemResult == 1) { if (CallFunction("TITLE_LOADGAME", false, false)) {//独自定義 state.SystemState = SystemStateCode.Openning_TitleLoadgame; } else {//標準のLOADGAME beginLoadGameOpening(); } } else//入力が正しくないならもう一回選択肢を書き直し、正しい選択を要求する。 {//RESUELASTLINEと同様の処理を行うように変更 console.deleteLine(1); console.PrintTemporaryLine("Invalid value"); console.updatedGeneration = true; openingInput(); //beginTitle(); } } void beginFirst() { state.SystemState = SystemStateCode.Normal; //連続調教コマンド処理中の状態が持ち越されていたらここで消しておく if (isCTrain) if (ClearCommands()) return; skipPrint = false; CallFunction("EVENTFIRST", true, true); } void endTitleLoadgame() { beginTitle(); } void beginTrain() { vEvaluator.UpdateInBeginTrain(); state.SystemState = SystemStateCode.Train_CallEventTrain; //EVENTTRAINを呼び出してTrain_CallEventTrainへ移行。 if (!CallFunction("EVENTTRAIN", false, true)) { //存在しなければスキップしてTrain_CallEventTrainが終わったことにする。 endCallEventTrain(); } } List coms = new List(); bool isCTrain; int count; bool skipPrint; public bool SkipPrint { get => skipPrint; set { skipPrint = value; } } void endCallEventTrain() { if (vEvaluator.NEXTCOM >= 0) {//NEXTCOMの処理 state.SystemState = SystemStateCode.Train_CallEventCom; vEvaluator.SELECTCOM = vEvaluator.NEXTCOM; vEvaluator.NEXTCOM = 0; //-1ではなく0を代入するのでERB側で変更しない限り無限にはまることになるがeramakerからの仕様である。 callEventCom(); } else { //if (!isCTrain) //{ //SHOW_STATUSを呼び出してTrain_CallShowStatusへ移行。 if (isCTrain) skipPrint = true; CallFunction("SHOW_STATUS", true, false); state.SystemState = SystemStateCode.Train_CallShowStatus; //} //else //{ //連続調教モードならCOMABLE処理へ // endCallShowStatus(); //} } } void endCallShowStatus() { //SHOW_STATUSが終わったらComAbleXXの呼び出し状態をリセットしてTrain_CallComAbleXXへ移行。 state.SystemState = SystemStateCode.Train_CallComAbleXX; _lastCalledComable = -1; _lastAddCom = -1; printComCount = 0; for (int i = 0; i < _comAble.Length; i++) _comAble[i] = -1; endCallComAbleXX(); } string getTrainComString(int trainCode, int comNo) { string trainName = Translation.translate(_trainName[trainCode], "Train", true); return string.Format("{0}[{1,3}]", trainName, comNo); } int printComCount; void endCallComAbleXX() { //選択肢追加。RESULTが0の場合は選択肢の番号のみ増やして追加はしない。 if ((_lastCalledComable >= 0) && (_trainName[_lastCalledComable] != null)) { _lastAddCom++; if (vEvaluator.RESULT != 0) { _comAble[_lastAddCom] = _lastCalledComable; if (!isCTrain) { console.PrintC(getTrainComString(_lastCalledComable, _lastAddCom), true); printComCount++; if ((Config.Config.PrintCPerLine > 0) && (printComCount % Config.Config.PrintCPerLine == 0)) console.PrintFlush(false); } console.RefreshStrings(false); } } //ComAbleXXの呼び出し。train.csvに定義されていないものはスキップ、ComAbleXXが見つからなければREUTRN 1と同様に扱う。 while (++_lastCalledComable < _trainName.Length) { if (_trainName[_lastCalledComable] == null) continue; string comName = string.Format("COM_ABLE{0}", _lastCalledComable); if (!CallFunction(comName, false, false)) { _lastAddCom++; if (Config.Config.ComAbleDefault == 0) continue; _comAble[_lastAddCom] = _lastCalledComable; if (!isCTrain) { console.PrintC(getTrainComString(_lastCalledComable, _lastAddCom), true); printComCount++; if ((Config.Config.PrintCPerLine > 0) && (printComCount % Config.Config.PrintCPerLine == 0)) console.PrintFlush(false); } continue; } console.RefreshStrings(false); return; } //全部検索したら終了し、SHOW_USERCOMを呼び出す。 if (_lastCalledComable >= _trainName.Length) { state.SystemState = SystemStateCode.Train_CallShowUserCom; //if (!isCTrain) //{ console.PrintFlush(false); console.RefreshStrings(false); CallFunction("SHOW_USERCOM", true, false); //} //else // endCallShowUserCom(); } } void endCallShowUserCom() { if (skipPrint) skipPrint = false; vEvaluator.UpdateAfterShowUsercom(); if (!isCTrain) { //数値入力待ち状態にしてTrain_WaitInputへ移行。 SetWaitInput(); state.SystemState = SystemStateCode.Train_WaitInput; } else { if (count < coms.Count) { _systemResult = coms[count]; count++; trainWaitInput(); } } } void trainWaitInput() { int selectCom = -1; if (!isCTrain) { if ((_systemResult >= 0) && (_systemResult < _comAble.Length)) selectCom = _comAble[_systemResult]; } else { for (int i = 0; i < _comAble.Length; i++) { if (_comAble[i] == _systemResult) selectCom = (int)_systemResult; } console.PrintSingleLine(string.Format("<Executed command:{0}/{1}>", count, coms.Count)); } //TrainNameが定義されていて使用可能(COMABLEが非0を返した)である if (selectCom >= 0) { vEvaluator.SELECTCOM = selectCom; callEventCom(); } else {//されていない。 if (isCTrain) console.PrintSingleLine("Unable to execute command"); vEvaluator.RESULT = _systemResult; state.SystemState = SystemStateCode.Train_CallEventComEnd; CallFunction("USERCOM", true, false); //COM中の必要なことは全部USERCOM内でやる。 } } private Int64 doTrainSelectCom = -1; void doTrain() { vEvaluator.UpdateAfterShowUsercom(); vEvaluator.SELECTCOM = doTrainSelectCom; callEventCom(); } void callEventCom() { vEvaluator.UpdateAfterInputCom(); state.SystemState = SystemStateCode.Train_CallEventCom; if (!CallFunction("EVENTCOM", false, true)) endEventCom(); } void endEventCom() { long selectCom = vEvaluator.SELECTCOM; string comName = string.Format("COM{0}", selectCom); state.SystemState = SystemStateCode.Train_CallComXX; CallFunction(comName, true, false); } void endCallComXX() { //実行に失敗した if (vEvaluator.RESULT == 0) { //Com終了。 endCallEventComEnd(); } else {//成功したならSOURCE_CHECKへ移行。 state.SystemState = SystemStateCode.Train_CallSourceCheck; CallFunction("SOURCE_CHECK", true, false); } } void endCallSourceCheck() { //SOURCEはここでリセット vEvaluator.UpdateAfterSourceCheck(); //EVENTCOMENDを呼び出してTrain_CallEventComEndへ移行。 state.SystemState = SystemStateCode.Train_CallEventComEnd; //EVENTCOMENDが存在しない、またはEVENTCOMEND内でWAIT系命令が行われない場合、EVENTCOMEND後にWAITを追加する。 NeedWaitToEventComEnd = true; if (!CallFunction("EVENTCOMEND", false, true)) { //見つからないならスキップしてTrain_CallEventComEndが終了したとみなす。 endCallEventComEnd(); } } public bool NeedWaitToEventComEnd; bool needCheck = true; void endCallEventComEnd() { if (console.LastLineIsTemporary && !isCTrain && needCheck) { if (console.LastLineIsEmpty) { console.deleteLine(2); console.PrintTemporaryLine("Invalid value"); } console.updatedGeneration = true; endCallShowUserCom(); } else { if (isCTrain && count == coms.Count) { isCTrain = false; skipPrint = false; coms.Clear(); count = 0; if (CallFunction("CALLTRAINEND", false, false)) { needCheck = false; return; } } needCheck = true; ////1.701 ここでWAITは不要だった。 ////setWait(); //1.703 やはり必要な場合もあった if (NeedWaitToEventComEnd) SetWait(); NeedWaitToEventComEnd = false; //SHOW_STATUSからやり直す。 //処理はTrain_CallEventTrainと同じ。 endCallEventTrain(); } } void beginAfterTrain() { //連続調教モード中にここに来る場合があるので、ここで解除 if (isCTrain) if (ClearCommands()) return; skipPrint = false; state.SystemState = SystemStateCode.Normal; //EVENTENDを呼び出す。exe側が状態を把握する必要が無くなるのでNormalへ移行。 CallFunction("EVENTEND", true, true); } void beginAblup() { //連続調教コマンド処理中の状態が持ち越されていたらここで消しておく if (isCTrain) if (ClearCommands()) return; skipPrint = false; state.SystemState = SystemStateCode.Ablup_CallShowJuel; //SHOW_JUELを呼び出しAblup_CallShowJuelへ移行。 CallFunction("SHOW_JUEL", true, false); } void endCallShowJuel() { state.SystemState = SystemStateCode.Ablup_CallShowAblupSelect; //SHOW_ABLUP_SELECTを呼び出しAblup_CallAblupSelectへ移行。 CallFunction("SHOW_ABLUP_SELECT", true, false); } void endCallShowAblupSelect() { //数値入力待ち状態にしてAblup_WaitInputへ移行。 SetWaitInput(); state.SystemState = SystemStateCode.Ablup_WaitInput; } void ablupWaitInput() { //定義されていなくても100未満ならABLUPが呼ばれ、USERABLUPは呼ばれない。そうしないと[99]反発刻印とかが出来ない。 if ((_systemResult >= 0) && (_systemResult < 100)) { state.SystemState = SystemStateCode.Ablup_CallAblupXX; string ablName = string.Format("ABLUP{0}", _systemResult); if (!CallFunction(ablName, false, false)) { //見つからなければ終了 console.deleteLine(1); console.PrintTemporaryLine("Invalid value"); console.updatedGeneration = true; endCallShowAblupSelect(); } } else { vEvaluator.RESULT = _systemResult; state.SystemState = SystemStateCode.Ablup_CallAblupXX; CallFunction("USERABLUP", true, false); } } void endCallAblupXX() { if (console.LastLineIsTemporary) { if (console.LastLineIsEmpty) { console.deleteLine(2); console.PrintTemporaryLine("Invalid value"); } console.updatedGeneration = true; endCallShowAblupSelect(); } else beginAblup(); } void beginTurnend() { //連続調教コマンド処理中の状態が持ち越されていたらここで消しておく if (isCTrain) if (ClearCommands()) return; skipPrint = false; //EVENTTURNENDを呼び出しNormalへ移行 CallFunction("EVENTTURNEND", true, true); state.SystemState = SystemStateCode.Normal; } void beginShop() { //連続調教コマンド処理中の状態が持ち越されていたらここで消しておく if (isCTrain) if (ClearCommands()) return; skipPrint = false; state.SystemState = SystemStateCode.Shop_CallEventShop; //EVENTSHOPを呼び出してShop_CallEventShopへ移行。 if (!CallFunction("EVENTSHOP", false, true)) { //存在しなければスキップしてShop_CallEventShopが終わったことにする。 endCallEventShop(); } } void endCallEventShop() { saveTarget = -1; if (Config.Config.AutoSave && state.calledWhenNormal) beginAutoSave(); else { state.SystemState = SystemStateCode.AutoSave_Skipped; endAutoSaveCallSaveInfo(); } } void beginAutoSave() { if (CallFunction("SYSTEM_AUTOSAVE", false, false)) {//@SYSTEM_AUTOSAVEが存在するならそれを使う。 state.SystemState = SystemStateCode.AutoSave_CallUniqueAutosave; return; } saveTarget = AutoSaveIndex; vEvaluator.SAVEDATA_TEXT = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " "; state.SystemState = SystemStateCode.AutoSave_CallSaveInfo; if (!CallFunction("SAVEINFO", false, false)) endAutoSaveCallSaveInfo();//存在しなければスキップ } void endAutoSaveCallSaveInfo() { if (saveTarget == AutoSaveIndex) { if (!vEvaluator.SaveTo(saveTarget, vEvaluator.SAVEDATA_TEXT)) { console.PrintError("オートセーブ中に予期しないエラーが発生しました"); console.PrintError("オートセーブをスキップします"); console.ReadAnyKey(); } } endAutoSave(); } void endAutoSave() { if (state.isBegun) { state.Begin(); return; } state.SystemState = SystemStateCode.Shop_CallShowShop; //SHOW_SHOPを呼び出しShop_CallShowShopへ移行 CallFunction("SHOW_SHOP", true, false); } void endCallShowShop() { //数値入力待ち状態にしてShop_WaitInputへ移行。 SetWaitInput(); state.SystemState = SystemStateCode.Shop_WaitInput; } //PRINT_SHOPITEMとは独立している。 //BOUGHTが100以上のアイテムが有り、ITEMSALESがTRUEだとしても強制的に@USERSHOP行き。 void shopWaitInput() { if ((_systemResult >= 0) && (_systemResult < Config.Config.MaxShopItem)) { if (vEvaluator.ItemSales(_systemResult)) { if (vEvaluator.BuyItem(_systemResult)) { state.SystemState = SystemStateCode.Shop_CallEventBuy; //EVENTBUYを呼び出しShop_CallEventBuyへ移行 if (!CallFunction("EVENTBUY", false, true)) endCallEventBuy(); return; } //console.Print("お金が足りません。"); //console.NewLine(); console.deleteLine(1); console.PrintTemporaryLine("お金が足りません。"); } else { //console.Print("売っていません。"); //console.NewLine(); console.deleteLine(1); console.PrintTemporaryLine("売っていません。"); } //購入に失敗した場合、endCallEventShop()に戻す。 //endCallEventShop(); endCallShowShop(); } else { //RESULTを更新 vEvaluator.RESULT = _systemResult; //USERSHOPを呼び出しShop_CallEventBuyへ移行 CallFunction("USERSHOP", true, false); state.SystemState = SystemStateCode.Shop_CallEventBuy; } } void endCallEventBuy() { if (console.LastLineIsTemporary) { if (console.LastLineIsEmpty) { console.deleteLine(2); console.PrintTemporaryLine("Invalid value"); } console.updatedGeneration = true; endCallShowShop(); } else { //最初に戻る endAutoSave(); } } void beginDataLoaded() { state.SystemState = SystemStateCode.LoadData_CallSystemLoad; if (!CallFunction("SYSTEM_LOADEND", false, false)) endSystemLoad();//存在しなければスキップ } void endSystemLoad() { state.SystemState = SystemStateCode.LoadData_CallEventLoad; //EVENTLOADを呼び出してLoadData_CallEventLoadへ移行。 if (!CallFunction("EVENTLOAD", false, true)) { //存在しなければスキップしてTrain_CallEventTrainが終わったことにする。 endAutoSave(); } } void endEventLoad() { //@EVENTLOAD中にBEGIN命令が行われればここには来ない。 //ここに来たらBEGIN SHOP扱い。オートセーブはしない。 endAutoSave(); } void beginSaveGame() { console.PrintSingleLine("Where do you want to save?"); state.SystemState = SystemStateCode.SaveGame_Begin; printSaveDataText(); } void beginLoadGame() { console.PrintSingleLine("What do you want to load?"); state.SystemState = SystemStateCode.LoadGame_Begin; printSaveDataText(); } void beginLoadGameOpening() { console.PrintSingleLine("Which save do you load?"); state.SystemState = SystemStateCode.LoadGameOpenning_Begin; printSaveDataText(); } bool[] dataIsAvailable = new bool[21]; bool isFirstTime = true; const int AutoSaveIndex = 99; int page; void printSaveDataText() { if (isFirstTime) { isFirstTime = false; dataIsAvailable = new bool[Config.Config.SaveDataNos + 1]; } int dataNo = 0; for (int i = 0; i < page; i++) { console.PrintFlush(false); console.Write(string.Format("[{0, 2}] Display slots {0, 2}~{1, 2}", i * 20, i * 20 + 19)); } for (int i = 0; i < 20; i++) { dataNo = page * 20 + i; if (dataNo == dataIsAvailable.Length - 1) break; dataIsAvailable[dataNo] = false; console.PrintFlush(false); console.Write(string.Format("[{0, 2}] ", dataNo)); if (!writeSavedataTextFrom(dataNo)) continue; dataIsAvailable[dataNo] = true; } for (int i = page; i < ((dataIsAvailable.Length - 2) / 20); i++) { console.PrintFlush(false); console.Write(string.Format("[{0, 2}] Display slots {0, 2}~{1, 2}", (i + 1) * 20, (i + 1) * 20 + 19)); } //オートセーブの処理は別途切り出し(表示処理の都合上) dataIsAvailable[dataIsAvailable.Length - 1] = false; if (state.SystemState != SystemStateCode.SaveGame_Begin) { dataNo = AutoSaveIndex; console.PrintFlush(false); console.Write(string.Format("[{0, 2}] ", dataNo)); if (writeSavedataTextFrom(dataNo)) dataIsAvailable[dataIsAvailable.Length - 1] = true; } console.RefreshStrings(false); //描画全部終わり console.PrintSingleLine("[100] Return"); SetWaitInput(); if (state.SystemState == SystemStateCode.SaveGame_Begin) state.SystemState = SystemStateCode.SaveGame_WaitInput; else if (state.SystemState == SystemStateCode.LoadGame_Begin) state.SystemState = SystemStateCode.LoadGame_WaitInput; else// if (state.SystemState == SystemStateCode.LoadGameOpenning_Begin) state.SystemState = SystemStateCode.LoadGameOpenning_WaitInput; //きちんと処理されてるので、ここには来ない //else // throw new ExeEE("異常な状態"); } int saveTarget = -1; void saveGameWaitInput() { if (_systemResult == 100) { //キャンセルなら直前の状態を呼び戻す loadPrevState(); return; } if (((int)_systemResult / 20) != page && _systemResult != AutoSaveIndex && (_systemResult >= 0 && _systemResult < dataIsAvailable.Length - 1)) { page = (int)_systemResult / 20; state.SystemState = SystemStateCode.SaveGame_Begin; printSaveDataText(); return; } bool available = false; if ((_systemResult >= 0) && (_systemResult < dataIsAvailable.Length - 1)) available = dataIsAvailable[_systemResult]; else {//入力しなおし console.deleteLine(1); console.PrintTemporaryLine("Invalid value"); console.updatedGeneration = true; SetWaitInput(); return; } saveTarget = (int)_systemResult; //既存データがあるなら選択肢を表示してSaveGame_WaitInputOverwriteへ移行。 if (available) { console.PrintSingleLine("Save already exists. Overwrite?"); console.PrintC("[0] Yes", false); console.PrintC("[1] No", false); SetWaitInput(); state.SystemState = SystemStateCode.SaveGame_WaitInputOverwrite; return; } //既存データがないなら「はい」を選んだことにして直接ジャンプ _systemResult = 0; saveGameWaitInputOverwrite(); } void saveGameWaitInputOverwrite() { if (_systemResult == 1)//いいえ { beginSaveGame(); return; } if (_systemResult != 0)//「はい」でもない {//入力しなおし console.deleteLine(1); console.PrintTemporaryLine("Invalid value"); console.updatedGeneration = true; SetWaitInput(); return; } vEvaluator.SAVEDATA_TEXT = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " "; state.SystemState = SystemStateCode.SaveGame_CallSaveInfo; if (!CallFunction("SAVEINFO", false, false)) endCallSaveInfo();//存在しなければスキップ } void endCallSaveInfo() { if (!vEvaluator.SaveTo(saveTarget, vEvaluator.SAVEDATA_TEXT)) { console.PrintError("Unexpected error while saving occured"); console.ReadAnyKey(); } loadPrevState(); } void loadGameWaitInput() { if (_systemResult == 100) {//キャンセルなら //オープニングならオープニングへ戻る if (state.SystemState == SystemStateCode.LoadGameOpenning_WaitInput) { beginTitle(); return; } //それ以外から来たなら直前の状態を呼び戻す loadPrevState(); return; } if (((int)_systemResult / 20) != page && _systemResult != AutoSaveIndex && (_systemResult >= 0 && _systemResult < dataIsAvailable.Length - 1)) { page = (int)_systemResult / 20; if (state.SystemState == SystemStateCode.LoadGameOpenning_WaitInput) state.SystemState = SystemStateCode.LoadGameOpenning_Begin; else state.SystemState = SystemStateCode.LoadGame_Begin; printSaveDataText(); return; } bool available = false; if ((_systemResult >= 0) && (_systemResult < dataIsAvailable.Length - 1)) available = dataIsAvailable[_systemResult]; else if (_systemResult == AutoSaveIndex) available = dataIsAvailable[dataIsAvailable.Length - 1]; else {//入力しなおし console.deleteLine(1); console.PrintTemporaryLine("Invalid value"); console.updatedGeneration = true; SetWaitInput(); return; } if (!available) { console.PrintSingleLine(_systemResult.ToString()); console.PrintError("No data found"); if (state.SystemState == SystemStateCode.LoadGameOpenning_WaitInput) { beginLoadGameOpening(); return; } beginLoadGame(); return; } if (!vEvaluator.LoadFrom((int)_systemResult)) throw new ExeEE("Unexpected error while loading save"); deletePrevState(); beginDataLoaded(); } void endNormal() { throw new CodeEE("Script execution terminated"); } void endReloaderb() { loadPrevState(); console.ReloadErbFinished(); } private bool writeSavedataTextFrom(int saveIndex) { EraDataResult result = vEvaluator.CheckData(saveIndex, EraSaveFileType.Normal); console.Write(result.DataMes); console.NewLine(); return result.State == EraDataState.OK; } } }