//===================================================================
//SaveInEvent.js
//イベント実行中もセーブを可能にするプラグイン
//===================================================================
//Copyright (c) 2018 蔦森くいな
//Released under the MIT license.
//http://opensource.org/licenses/mit-license.php
//-------------------------------------------------------------------
//blog   : http://paradre.com/
//Twitter: https://twitter.com/Kuina_T
//===================================================================
//＜更新情報＞
//  ver1.0.0 2018/02/10 初版
//===================================================================

/*:
 * @plugindesc イベント実行中にメニューを開いたりセーブできるようにするプラグインです
 * @author 蔦森くいな
 *
 * @help このプラグインをＯＮにすると、イベント実行中に
 * メニューを開いたりセーブをした場合のエラーを防ぎます。
 * 
 * また、セーブデータをロードした時も、
 * セーブした時点で表示されていた文章や選択肢から再開します。
 * 
 * 以下、簡単な制作例を紹介します
 * 
 * ■イベント実行中にメニュー画面やセーブ画面を開く方法
 * 並列処理イベントに
 * 「条件分岐：ボタン[シフト]が押されている」を設定し、
 * その中に「メニュー画面を開く」や「セーブ画面を開く」を設定します。
 * これでShiftキーを押すとイベント中でもセーブできます
 * 
 * ■注意点
 * このプラグインはマップ上で実行中のイベントや
 * コモンイベントにのみ対応しています。
 * バトル画面で実行されるイベントには対応していません。
 * また、並列処理で実行中のイベントにも対応していません。
 * 
 *
 * 利用規約：
 * このプラグインは商用・非商用を問わず無料でご利用いただけます。
 * 使用報告やクレジット表記も必要ありません。
 * どのようなゲームに使っても、どのように加工していただいても構いません。
 * MIT Licenseにつき著作権表示とライセンスURLは残しておいて下さい。
 */

function PD_SIE_PLUGIN() {
    throw new Error('This is a static class');
}

PD_SIE_PLUGIN.returnBaseIndex = function(interpreter){
    var baseIndex = interpreter._index;
    var commandList = interpreter._list;
    if(commandList){
        if(commandList[baseIndex-1]){
            switch(commandList[baseIndex-1].code){
                case 401:
                    baseIndex -= 1;
                    while (commandList[baseIndex].code !== 101){
                        baseIndex -= 1;
                    }
                    break;
                case 102:
                    baseIndex -= 1;
                    if(commandList[baseIndex-1] && commandList[baseIndex-1].code === 401){
                        baseIndex -= 1;
                        while (commandList[baseIndex].code !== 101){
                            baseIndex -= 1;
                        }
                    }
                    break;
                case 103:
                    baseIndex -= 1;
                    if(commandList[baseIndex-1] && commandList[baseIndex-1].code === 401){
                        baseIndex -= 1;
                        while (commandList[baseIndex].code !== 101){
                            baseIndex -= 1;
                        }
                    }
                    break;
                case 104:
                    baseIndex -= 1;
                    if(commandList[baseIndex-1] && commandList[baseIndex-1].code === 401){
                        baseIndex -= 1;
                        while (commandList[baseIndex].code !== 101){
                            baseIndex -= 1;
                        }
                    }
                    break;
                case 405:
                    baseIndex -= 1;
                    while (commandList[baseIndex].code !== 105){
                        baseIndex -= 1;
                    }
                    break;
            }
        }
    }
    return baseIndex;
};

(function() {
    'use strict';
    
    var pd_SIE_DataManager_saveGameWithoutRescue = DataManager.saveGameWithoutRescue;
    DataManager.saveGameWithoutRescue = function(savefileId) {
        var holdIndex = $gameMap._interpreter._index;
        $gameMap._interpreter._index = PD_SIE_PLUGIN.returnBaseIndex($gameMap._interpreter);
        var childInterpreter = $gameMap._interpreter._childInterpreter;
        var holdChildIndex = [];
        while(childInterpreter !== null){
            holdChildIndex.push(childInterpreter._index);
            childInterpreter._index = PD_SIE_PLUGIN.returnBaseIndex(childInterpreter);
            childInterpreter = childInterpreter._childInterpreter;
        }
        var result = pd_SIE_DataManager_saveGameWithoutRescue.apply(this, arguments);
        $gameMap._interpreter._index = holdIndex;
        childInterpreter = $gameMap._interpreter._childInterpreter;
        while(childInterpreter !== null){
            childInterpreter._index = holdChildIndex.shift();
            childInterpreter = childInterpreter._childInterpreter;
        }
        
        return result;
    };
    
    var pd_SIE_Game_Temp_initialize = Game_Temp.prototype.initialize;
    Game_Temp.prototype.initialize = function() {
        this._pd_SIE_EventFrag = null;
        pd_SIE_Game_Temp_initialize.apply(this, arguments);
    };
    
    var pd_SIE_Scene_Map_create = Scene_Map.prototype.create;
    Scene_Map.prototype.create = function() {
        if(!SceneManager.isPreviousScene(Scene_Map) && $gameTemp._pd_SIE_EventFrag === false){
            var commandList = $gameMap._interpreter._list;
            if(commandList){
                var baseIndex = PD_SIE_PLUGIN.returnBaseIndex($gameMap._interpreter);
                var command = commandList[baseIndex];
                if(command){
                    var childInterpreter = $gameMap._interpreter._childInterpreter;
                    if(childInterpreter === null){
                        if(command.code === 101 ||
                           command.code === 102){
                            $gameMap._interpreter._index = baseIndex;
                            $gameMessage.clear();
                            $gameTemp._pd_SIE_EventFrag = true;
                        }
                    }else{
                        var childBaseIndex;
                        var childCommand;
                        while(childInterpreter !== null){
                            childBaseIndex = PD_SIE_PLUGIN.returnBaseIndex(childInterpreter);
                            childCommand = childInterpreter._list[childBaseIndex];
                            if(childCommand){
                                if(childCommand.code === 101 ||
                                   childCommand.code === 102){
                                    childInterpreter._index = childBaseIndex;
                                    $gameMessage.clear();
                                }
                            }
                            childInterpreter = childInterpreter._childInterpreter;
                        }
                    }
                }
            }
        }
        pd_SIE_Scene_Map_create.apply(this, arguments);
    };
    
    var pd_SIE_Scene_Map_start = Scene_Map.prototype.start;
    Scene_Map.prototype.start = function() {
        pd_SIE_Scene_Map_start.apply(this, arguments);
        if($gameTemp._pd_SIE_EventFrag === true){
            $gameMap._interpreter.executeCommand();
        }
        $gameTemp._pd_SIE_EventFrag = false;
    };
    
})();
